В чем разница между a.getClass() и A.class на Яве?
в Java какие плюсы/минусы существуют вокруг выбора использовать a.getClass() или A.class? Либо может быть использован везде, где Class<?> ожидается, но я предполагаю, что будет производительность или другие тонкие преимущества для использования обоих в разных обстоятельствах (так же, как и с Class.forName() и ClassLoader.loadClass().
6 ответов:
Я бы не стал сравнивать их с точки зрения плюсов/минусов, поскольку у них разные цели, и редко есть "выбор" между ними.
a.getClass()возвращает времени выполнения типа наa. То есть, если у васA a = new B();затемa.getClass()вернетBкласса.
A.classоценивает вAкласс статически, и используется для других целей, часто связанных с отображение.С точки зрения производительности, есть мая быть измеримой разницей, но я ничего не скажу об этом, потому что в конце концов это зависит от 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первый обычно включает в себя отправку виртуального метода и, следовательно, предположительно занимает больше времени для выполнения. То есть в конце виртуальной Java-машины, зависит от однако.
посмотрите на примеры ниже
a.getClass()!= A.class, т. е. a не является экземпляром A, но анонимного подкласса а
a.getClass()требуется экземпляр типа A
использовать
a.getClassкогда у вас есть экземпляр класса/типа и вы хотите получить точный тип его. в то время как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
есть одно отличие я хотел бы добавить. Допустим, у вас есть конструктор класса a, как показано ниже, с суперклассом, который принимает объект класса. Вы хотите, чтобы всякий раз, когда создается объект подкласса, объект класса подкласса должен быть передан суперклассу. Ниже код не будет компилироваться, так как вы не можете вызвать метод экземпляра в конструкторе. В том случае, если вы замените
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
Comments