在Java中,围绕使用a.getClass()
或选择存在哪些利弊A.class
?可以在Class<?>
预期的任何地方使用这两种方法,但是我想在不同的情况下使用这两种方法都会有性能或其他微妙的好处(就像with Class.forName()
和and一样ClassLoader.loadClass()
。)
在Java中,围绕使用a.getClass()
或选择存在哪些利弊A.class
?可以在Class<?>
预期的任何地方使用这两种方法,但是我想在不同的情况下使用这两种方法都会有性能或其他微妙的好处(就像with Class.forName()
和and一样ClassLoader.loadClass()
。)
Answers:
我不会在优点/缺点方面进行比较,因为它们具有不同的目的,并且很少在两者之间做出选择。
a.getClass()
返回运行时类型的a
。也就是说,如果你有A a = new B();
那么a.getClass()
将返回B
类。
A.class
静态地对A
类求值,并用于通常与反射相关的其他目的。
在性能方面,可能会有可测量的差异,但是我不会在此赘述,因为最终它取决于JVM和/或编译器。
这篇文章在这里已被重写为文章。
Class
代表该A.class
对象的类的对象,该对象又是的一个实例java.lang.Class
。
A.getClass().class
样
A
是一堂课,那真的没有意义。getClass
类上没有静态方法。
实际上,它们在哪里可以使用方面有所不同。A.class
在编译时工作,而a.getClass()
需要一个类型的实例,A
并在运行时工作。
性能可能也会有所不同。虽然A.class
可以由编译器解决,因为它知道的实际类型A
,这a.getClass()
是在运行时发生的虚拟方法调用。
作为参考,针对字节码的编译器通常针对以下问题发出以下指令Integer.getClass()
:
aload_1
invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class;
以及以下内容Integer.class
:
//const #3 = class #16; // java/lang/Integer
ldc_w #3; //class java/lang/Integer
前者通常会涉及虚拟方法的分派,因此大概需要更长的时间才能执行。最终这取决于JVM。
看下面的例子
a.getClass()!= A.class
,即a不是A的实例,而是A的匿名子类
a.getClass()
需要类型A的实例
使用a.getClass
时,你有类/类型的实例,你想获得它的确切类型。while a.class
在type
可用并要创建实例时使用。在编译时求值时,
还getClass()
返回实例的运行时类型.class
。
考虑到性能getClass()
和.class
,.class
具有比更好的性能 getClass()
。
范例:
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");
}
}
输出:
time (getClass()) : 79410 ns
time (.class) : 8032 ns
我想补充一个区别。假设您有一个具有以下构造函数的类,如下所示,该类带有一个带有Class对象的超类。您希望无论何时创建子类对象,都应将子类的类对象传递给超类。由于无法在构造函数中调用实例方法,因此以下代码无法编译。在这种情况下,如果您替换myObject.getClass()
为MyClass.class
。它将完美运行。
Class MyClass
{
private MyClass myObject = new MyClass();
public MyClass()
{
super(myObject.getClass()); //error line compile time error
}
}
有趣的是,上面示例中提到的性能差异似乎与其他原因有关。使用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");
} }
输出将类似于:
time (getClass()) :23506 ns
time (.class):23838 ns
切换呼叫顺序甚至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");
}}
输出:
time (.class):33108 ns
time (getClass()) :6622 ns
A.class.getClass()
样