[英]What is the difference between a.getClass() and A.class in Java?
In Java what pros/cons exist surrounding the choice to use a.getClass()
or A.class
?在 Java 中,围绕使用
a.getClass()
或A.class
的选择存在哪些优点/缺点? Either can be used wherever a Class<?>
is expected, but I imagine that there would be performance or other subtle benefits to using both in different circumstances (just like there are with Class.forName()
and ClassLoader.loadClass()
.两者都可以在需要
Class<?>
任何地方使用,但我想在不同的情况下使用两者会有性能或其他微妙的好处(就像Class.forName()
和ClassLoader.loadClass()
。
I wouldn't compare them in terms of pros/cons since they have different purposes and there's seldom a "choice" to make between the two.我不会在利弊方面比较它们,因为它们有不同的目的,而且两者之间很少有“选择”。
a.getClass()
returns the runtime type of a
. a.getClass()
返回的运行时类型a
。 Ie, if you have A a = new B();
即,如果你有
A a = new B();
then a.getClass()
will return the B
class.然后
a.getClass()
将返回B
类。
A.class
evaluates to the A
class statically , and is used for other purposes often related to reflection. A.class
静态评估为A
类,并用于其他经常与反射相关的目的。
In terms of performance, there may be a measurable difference, but I won't say anything about it because in the end it is JVM and/or compiler dependent.在性能方面,可能存在可测量的差异,但我不会对此进行任何说明,因为最终它取决于 JVM 和/或编译器。
This post has been rewritten as an article here .这篇文章在这里被改写为一篇文章。
They are actually different with regards to where you can use them.它们实际上在您可以使用它们的地方方面有所不同。
A.class
works at compile time while a.getClass()
requires an instance of type A
and works at runtime. A.class
在编译时工作,而a.getClass()
需要类型A
的实例并在运行时工作。
There may be a performance difference as well.也可能存在性能差异。 While
A.class
can be resolved by the compiler because it knows the actual type of A
, a.getClass()
is a virtual method call happening at runtime.虽然
A.class
可以由编译器解析,因为它知道A
的实际类型,但a.getClass()
是在运行时发生的虚拟方法调用。
For reference, a compiler targeting bytecode typically emits the following instructions for Integer.getClass()
:作为参考,以字节码为目标的编译器通常会为
Integer.getClass()
发出以下指令:
aload_1
invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class;
and the following for Integer.class
:以及
Integer.class
的以下内容:
//const #3 = class #16; // java/lang/Integer
ldc_w #3; //class java/lang/Integer
The former would typically involve a virtual method dispatch and therefore presumably take longer time to execute.前者通常涉及虚拟方法分派,因此可能需要更长的时间来执行。 That is in the end JVM-dependent however.
然而,这最终取决于 JVM。
have a look at the examples below看看下面的例子
a.getClass()!= A.class
, ie a is not an instance of A but of an anonymous sub class of A a.getClass()!= A.class
,即 a 不是 A 的实例,而是 A 的匿名子类
a.getClass()
requires an instance of type A a.getClass()
需要一个类型为 A 的实例
Use a.getClass
when you have an instance of class/type and you want to get exact type of it.当您有一个类/类型的实例并且想要获得它的确切类型时,请使用
a.getClass
。 while a.class
is used when you have type
available and you want to create instance of it.而
a.class
当您有可用的type
并且想要创建它的实例时使用。
Also getClass()
returns runtime type of instance while .class
is evaluated at compile time. getClass()
返回实例的运行时类型,而.class
在编译时进行评估。
Considering performance of getClass()
and .class
, .class
has better performance than getClass()
.考虑到
getClass()
和.class
性能, .class
比getClass()
有更好的性能。
Example :例子 :
public class PerfomanceClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
long time=System.nanoTime();
Class class1="String".getClass();
class1="String".getClass();
class1="String".getClass();
class1="String".getClass();
System.out.println("time (getClass()) :"+(System.nanoTime()-time)+" ns");
long time2=System.nanoTime();
Class class2=String.class;
class2=String.class;
class2=String.class;
class2=String.class;
System.out.println("time (.class):"+(System.nanoTime()-time2)+" ns");
}
}
Output :输出 :
time (getClass()) : 79410 ns
time (.class) : 8032 ns
There is one difference i would like to add.我想补充一个区别。 Let us say you have a class a constructor as shown below with a super class which takes a Class object.
假设您有一个构造函数类,如下所示,其中有一个带有 Class 对象的超类。 You want that whenever a subclass object is created the subClass' class object should be passed to the super class.
您希望无论何时创建子类对象,都应将子类的类对象传递给超类。 Below code will not compile as you cannot call an instance method in a constructor.
下面的代码将无法编译,因为您无法在构造函数中调用实例方法。 In that case if you replace
myObject.getClass()
with MyClass.class
.在这种情况下,如果您将
myObject.getClass()
替换为MyClass.class
。 It will run perfectly.它将完美运行。
Class MyClass
{
private MyClass myObject = new MyClass();
public MyClass()
{
super(myObject.getClass()); //error line compile time error
}
}
Interestingly the differences in performance mentioned in the example above, seem to be related to other reasons.有趣的是,上面示例中提到的性能差异似乎与其他原因有关。 Using 3 different Classes, in average the performance will be nearly the same :
使用 3 个不同的类,平均而言,性能几乎相同:
import java.util.LinkedHashMap;
public class PerfomanceClass {
public static void main(String[] args) {
long time = System.nanoTime();
Class class1 = "String".getClass();
Class class11 = "Integer".getClass();
Class class111 = "LinkedHashMap".getClass();
System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");
long time2 = System.nanoTime();
Class class2 = String.class;
Class class22 = Integer.class;
Class class222 = LinkedHashMap.class;
System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");
} }
The Output will be something like :输出将类似于:
time (getClass()) :23506 ns
time (.class):23838 ns
And switching the order of the calls will even result in getClass()
being faster.切换调用顺序甚至会导致
getClass()
更快。
import java.util.LinkedHashMap;
public class PerfomanceClass {
public static void main(String[] args) {
long time2 = System.nanoTime();
Class class2 = LinkedHashMap.class;
System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");
long time = System.nanoTime();
Class class1 = "LinkedHashMap".getClass();
System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");
}}
Output:输出:
time (.class):33108 ns
time (getClass()) :6622 ns
p.getClass()
, where the p
is an instance of an object, returns the runtime class of this object p
. p.getClass()
,其中p
是一个对象的实例,返回这个对象p
的运行时类。 p
cannot be a type which will cause a compile-time error, it should be an instance of an object. p
不能是会导致编译时错误的类型,它应该是对象的实例。
// B extends A
A a = new B();
System.out.println(a.getClass());
//output: class B
p.class
is an expression. p.class
是一个表达式。 The .class
is called the class syntax. .class
称为类语法。 p
is a type. p
是一种类型。 It can be the name of a class, interface or array and even a primitive type.它可以是类、接口或数组的名称,甚至是原始类型。
a.getClass() == B.class
. a.getClass() == B.class
。
If a type is available and there is an instance then it is possible to use getClass
method to get the name of the type.如果一个类型可用并且有一个实例,那么可以使用
getClass
方法来获取类型的名称。 Otherwise, use the .class
syntax否则,使用
.class
语法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.