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

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

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

  • 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 
  • Узнайте, какие classы данного API используются
  • GetProperties () возвращает все свойства иерархии наследования интерфейса
  • Почему C ++ не имеет отражения?
  • Любой способ вызвать частный метод?
  • Есть ли способ «переопределить» метод с reflectionм?
  • Как получить имя переменной с помощью отражения?
  • Поиск различий свойств между двумя объектами C #
  • Неплохо ли использовать рефлексию в модульном тестировании?
  • Java - получить список всех classов, загруженных в JVM
  • Как вызвать частный статический метод с использованием отражения (Java)?
  • Как запретить разработчикам использовать reflection для доступа к приватным методам и конструкторам в Java?
  • Interesting Posts

    Как удалить верхнее и нижнее пространство на текстовом экране Android

    Зачем мне нужно несколько символов EOF (CTRL + Z)?

    Импорт пакета. * Vs import package.SpecificType

    Что технически неправильно при быстрой перестановке ОС?

    Как разместить кеш SuperFetch на SSD?

    5 звуковых сигналов с установленной Xeon E3-1230L V3?

    При архивировании на DVD, должен ли я сделать зеркальную копию, подобную RAID 1?

    Различия между Oracle JDK и OpenJDK

    Как сохранить любое окно «Всегда сверху»?

    Загрузить файл из формы Html (multipart / form-data) в службу WCF REST как stream без streamовой передачи входных данных всей формы?

    Как я могу использовать новый модуль Perl без разрешения на установку?

    onKeyListener не работает с мягкой клавиатурой (Android)

    В ответ на вопрос, как добавить сообщение об ошибке в сводку проверки?

    Есть ли расширение Google Chrome, которое действует как закладки быстрого поиска ключевых слов Firefox?

    Каков наилучший способ объявить глобальную переменную в Angular 2 / Typcript

    Давайте будем гением компьютера.