Quelle est la différence entre a.getClass () et A.class en Java?

En Java, quels sont les avantages / inconvénients a.getClass() au choix d’utiliser a.getClass() ou A.class ? Soit peut être utilisé partout où une Class Est attendue, mais j’imagine qu’il y aurait des performances ou d’autres avantages subtils à utiliser les deux dans des circonstances différentes (comme il y en a avec Class.forName() et ClassLoader.loadClass() .

Je ne les comparerais pas en termes de pour et de contre, car ils ont des objectives différents et il y a rarement un “choix” à faire entre les deux.

  • a.getClass() renvoie le type d’exécution d’ a . C’est-à-dire si vous avez A a = new B(); alors a.getClass() retournera la classe B

  • A.class évalue statiquement la classe A et est utilisée à d’autres fins souvent liées à la reflection.

En termes de performances, il peut y avoir une différence mesurable, mais je ne dirai rien à ce sujet car au final, cela dépend de JVM et / ou du compilateur.


Cet article a été réécrit comme un article ici .

Ils sont en réalité différents en ce qui concerne où vous pouvez les utiliser. A.class fonctionne à la compilation, tandis que a.getClass() requirejs une instance de type A et fonctionne à l’exécution.

Il peut également y avoir une différence de performance. Alors que A.class peut être résolu par le compilateur car il connaît le type réel de A , a.getClass() est un appel de méthode virtuel qui se produit à l’exécution.

À titre de référence, un bytecode ciblant le compilateur émet généralement les instructions suivantes pour Integer.getClass() :

 aload_1 invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class; 

et ce qui suit pour Integer.class :

 //const #3 = class #16; // java/lang/Integer ldc_w #3; //class java/lang/Integer 

Le premier impliquerait généralement un envoi de méthode virtuelle et par conséquent prendrait probablement plus de temps à exécuter. Cela dépend de la JVM.

jetez un oeil aux exemples ci-dessous

a.getClass()!= A.class , c.-à-d. a n’est pas une instance de A mais d’une sous-classe anonyme de A

a.getClass() nécessite une instance de type A

Utilisez a.getClass lorsque vous avez une instance de classe / type et que vous souhaitez en obtenir le type exact. tandis que a.class est utilisé lorsque vous avez un type disponible et que vous souhaitez en créer une instance.
getClass() renvoie également le type d’exécution de l’instance, tandis que la .class est évaluée au moment de la compilation.
Compte tenu des performances de getClass() et de .class , les performances de .class sont meilleures que getClass() de getClass() .
Exemple :

 public class PerfomanceClass { public static void main(Ssortingng[] args) { // TODO Auto-generated method stub long time=System.nanoTime(); Class class1="Ssortingng".getClass(); class1="Ssortingng".getClass(); class1="Ssortingng".getClass(); class1="Ssortingng".getClass(); System.out.println("time (getClass()) :"+(System.nanoTime()-time)+" ns"); long time2=System.nanoTime(); Class class2=Ssortingng.class; class2=Ssortingng.class; class2=Ssortingng.class; class2=Ssortingng.class; System.out.println("time (.class):"+(System.nanoTime()-time2)+" ns"); } } 

Sortie:

 time (getClass()) : 79410 ns time (.class) : 8032 ns 

Il y a une différence que j’aimerais append. Disons que vous avez une classe un constructeur comme indiqué ci-dessous avec une super classe qui prend un object Class. Vous voulez que chaque fois qu’un object de sous-classe est créé, l’object de classe subClass doit être transmis à la super-classe. Le code ci-dessous ne sera pas compilé car vous ne pouvez pas appeler une méthode d’instance dans un constructeur. Dans ce cas, si vous remplacez myObject.getClass() par MyClass.class . Il fonctionnera parfaitement.

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

Il est intéressant de noter que les différences de performance mentionnées dans l’exemple ci-dessus semblent être liées à d’autres raisons. En utilisant 3 classes différentes, les performances seront en moyenne les mêmes:

 import java.util.LinkedHashMap; public class PerfomanceClass { public static void main(Ssortingng[] args) { long time = System.nanoTime(); Class class1 = "Ssortingng".getClass(); Class class11 = "Integer".getClass(); Class class111 = "LinkedHashMap".getClass(); System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns"); long time2 = System.nanoTime(); Class class2 = Ssortingng.class; Class class22 = Integer.class; Class class222 = LinkedHashMap.class; System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns"); } } 

Le résultat sera quelque chose comme:

 time (getClass()) :23506 ns time (.class):23838 ns 

Et changer l’ordre des appels rendra même getClass() plus rapide.

 import java.util.LinkedHashMap; public class PerfomanceClass { public static void main(Ssortingng[] 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"); }} 

Sortie:

 time (.class):33108 ns time (getClass()) :6622 ns