В чем разница между a.getClass () и A.class в Java?

В Java, какие плюсы и минусы существуют вокруг выбора использования a.getClass() или A.class ? Любой из них может использоваться везде, где ожидается Class , Но я полагаю, что при использовании в разных обстоятельствах (например, с Class.forName() и ClassLoader.loadClass() будут иметь производительность или другие тонкие преимущества.

6 Solutions collect form web for “В чем разница между a.getClass () и A.class в Java?”

Я бы не стал сравнивать их с точки зрения плюсов и минусов, поскольку у них разные цели, и между ними редко бывает «выбор».

  • a.getClass() возвращает тип времени выполнения a . Т.е., если у вас есть A a = new B(); то a.getClass() вернет class B

  • A.class оценивает class A и используется для других целей, часто связанных с reflectionм.

Что касается производительности, может быть измеримая разница, но я ничего не буду говорить об этом, потому что в конечном итоге это JVM и / или компилятор.


Это сообщение было переписано как статья здесь .

Фактически они различаются в отношении того, где вы можете их использовать. 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, а анонимного подclassа A

a.getClass() требует экземпляра типа A

Используйте a.getClass если у вас есть экземпляр classа / типа, и вы хотите получить его точный тип. в то время как 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 конструктор, как показано ниже, с суперclassом, который принимает объект classа. Вы хотите, чтобы всякий раз, когда был создан объект подclassа, объект classа subClass должен быть передан суперclassу. Ниже код не будет компилироваться, поскольку вы не можете вызвать метод экземпляра в конструкторе. В этом случае, если вы замените myObject.getClass() на MyClass.class . Он будет работать отлично.

 Class MyClass { private MyClass myObject = new MyClass(); public MyClass() { super(myObject.getClass()); //error line compile time error } } 

Интересно, что различия в производительности, упомянутые в приведенном выше примере, по-видимому, связаны с другими причинами. Используя 3 разных classа, в среднем производительность будет почти одинаковой:

 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 
  • Как узнать, какой тип каждого объекта находится в ArrayList ?
  • Есть что-то вроде instanceOf (class C) в Java?
  • Обнаружение производных типов с использованием отражения
  • Вызов статического метода с использованием отражения
  • Почему отраженный доступ к защищенному / частному члену classа в C #?
  • Как определить, реализует ли тип определенного типа общего типа
  • Как получить свойство Static с reflectionм
  • Как перечислить все переменные classа
  • Есть ли способ «переопределить» метод с reflectionм?
  • Как создать экземпляр произвольного типа массива во время выполнения?
  • Как получить значение свойства с помощью отражения
  • Давайте будем гением компьютера.