La différence entre a.getClass () et A.class en Java

1. Vue d'ensemble

En Java, la classe java.lang.Class est le point d'entrée de toutes les opérations de réflexion . Une fois que nous avons un objet java.lang.Class , nous pouvons alors appeler les méthodes correspondantes pour obtenir les objets des classes de réflexion.

Dans ce tutoriel, nous discuterons des différences entre deux manières différentes d'obtenir un objet de java.lang.Class :

  • Appel de la méthode Object.getClass ()
  • Utilisation de la syntaxe .class

2. Brève introduction aux deux approches

La méthode Object.getClass () est une méthode d'instance de la classe Object . Si nous avons un objet, nous pouvons appeler object.getClass () pour obtenir l' objet Class de son type.

De même, nous pouvons utiliser la syntaxe ClassName.class pour obtenir l' objet Class du type. Un exemple peut l'expliquer clairement:

@Test public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult() { String str = "I am an object of the String class"; Class fromStrObject = str.getClass(); Class clazz = String.class; assertSame(fromStrObject, clazz); } 

Dans la méthode de test ci-dessus, nous essayons d'obtenir l' objet Class de la classe String en utilisant les deux méthodes que nous avons mentionnées. Enfin, la méthode d'assertion nous indique que les deux objets Class sont la même instance.

Cependant, il existe des différences entre les deux approches. Regardons-les de plus près.

3. Le type d'exécution et le type statique

Passons rapidement en revue l'exemple précédent. Lorsque nous appelons la méthode str.getClass () , nous obtenons le type d'exécution de l' objet str . D'autre part, String.class évalue la classe String de manière statique . Dans cet exemple, le type d'exécution de str et le String.class sont identiques.

Cependant, ils peuvent être différents si l'héritage de classe rejoint le groupe. Voyons deux classes simples:

public class Animal { protected int numberOfEyes; } public class Monkey extends Animal { // monkey stuff }

Maintenant, instancions un objet de la classe Animal et faisons un autre test:

@Test public void givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult() { Animal animal = new Monkey(); Class runtimeType = animal.getClass(); Class staticType = Animal.class; assertSame(staticType, runtimeType); } 

Si nous exécutons le test ci-dessus, nous obtiendrons un échec du test:

java.lang.AssertionError: .... Expected :class com.baeldung.getclassobject.Animal Actual :class com.baeldung.getclassobject.Monkey

Dans la méthode de test, même si nous avons instancié l' objet animal par Animal animal = new Monkey (); au lieu de Monkey animal = new Monkey (); , le type d'exécution de l' objet animal est toujours Monkey. En effet, l' objet animal est une instance de Monkey au moment de l'exécution.

Cependant, lorsque nous obtenons le type statique de la classe Animal , le type est toujours Animal .

4. Gestion des types primitifs

Lorsque nous écrivons du code Java, nous utilisons assez souvent des types primitifs. Essayons d'obtenir un objet Class d'un type primitif en utilisant l' approche object.getClass () :

int number = 7; Class numberClass = number.getClass();

Si nous essayons de compiler le code ci-dessus, nous obtiendrons une erreur de compilation:

Error: java: int cannot be dereferenced

Le compilateur ne peut pas déréférencer la variable numérique car il s'agit d'une variable primitive. Par conséquent, la méthode object.getClass () ne peut pas nous aider à obtenir l' objet Class d'un type primitif.

Voyons si nous pouvons obtenir le type primitif en utilisant la syntaxe .class :

@Test public void givenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks() { Class intType = int.class; assertNotNull(intType); assertEquals("int", intType.getName()); assertTrue(intType.isPrimitive()); } 

Ainsi, nous pouvons obtenir l' objet Class du type primitif int via int.class . Dans Java version 9 et ultérieure, un objet Class de type primitif appartient au module java.base .

Comme le montre le test, la syntaxe .class est un moyen simple d'obtenir l' objet Class d'un type primitif.

5. Obtenir la classe sans instance

Nous avons appris que la méthode object.getClass () peut nous donner l' objet Class de son type d'exécution.

Maintenant, considérons le cas où nous voulons obtenir un objet Class d'un type, mais nous ne pouvons pas obtenir une instance du type cible car c'est une classe abstraite , une interface ou une classe ne permet pas l'instanciation:

public abstract class SomeAbstractClass { // ... } interface SomeInterface { // some methods ... } public class SomeUtils { private SomeUtils() { throw new RuntimeException("This Util class is not allowed to be instantiated!"); } // some public static methods... } 

Dans ces cas, nous ne pouvons pas obtenir les objets Class de ces types en utilisant la méthode object.getClass () , mais nous pouvons toujours utiliser la syntaxe .class pour en obtenir les objets Class :

@Test public void givenTypeCannotInstantiate_whenGetTypeStatically_thenGetTypesSuccefully() { Class interfaceType = SomeInterface.class; Class abstractClassType = SomeAbstractClass.class; Class utilClassType = SomeUtils.class; assertNotNull(interfaceType); assertTrue(interfaceType.isInterface()); assertEquals("SomeInterface", interfaceType.getSimpleName()); assertNotNull(abstractClassType); assertEquals("SomeAbstractClass", abstractClassType.getSimpleName()); assertNotNull(utilClassType); assertEquals("SomeUtils", utilClassType.getSimpleName()); } 

Comme le montre le test ci-dessus, la syntaxe .class peut obtenir les objets Class pour ces types.

Par conséquent, lorsque nous voulons avoir l' objet Class , mais que nous ne pouvons pas obtenir une instance du type, la syntaxe .class est la voie à suivre.

6. Conclusion

Dans cet article, nous avons appris deux méthodes différentes pour obtenir l' objet Class d'un type: la méthode object.getClass () et la syntaxe .class .

Plus tard, nous avons discuté de la différence entre les deux approches. Le tableau suivant peut nous donner un aperçu clair:

object.getClass () SomeClass.class
Objets de classe Le type d' objet d' exécution Le type statique de SomeClass
Types primitifs - Fonctionne simplement
Interfaces, classes abstraites ou classes qui ne peuvent pas être instanciées - Fonctionne simplement

Comme toujours, le code source complet de l'article est disponible à l'adresse over sur GitHub.