Récupération d’un nom de classe en Java

Récupération d'un nom de classe en Java

1. Vue d'ensemble

Dans ce didacticiel, nous allons découvrir quatre façons de récupérer le nom d'une classe à partir de méthodes sur l'APIClass:getSimpleName(), getName(), getTypeName() etgetCanonicalName()

Ces méthodes peuvent être déroutantes en raison de leurs noms similaires et de leurs Javadocs quelque peu vagues. Ils ont également certaines nuances en ce qui concerne les types primitifs, les types d'objet, les classes internes ou anonymes et les tableaux.

2. Récupération d'un nom simple

Commençons par la méthodegetSimpleName().

En Java, il existe deux types de noms:simple etqualified. A simple name consists of a unique identifier while a qualified name is a sequence of simple names separated by dots.

Comme son nom l'indique,getSimpleName() renvoie le nom simple de la classe sous-jacente, c'est-à-direthe name it has been given in the source code.

Imaginons le cours suivant:

package com.example.className;
public class RetrieveClassName {}

Son nom simple seraitRetrieveClassName:

assertEquals("RetrieveClassName", RetrieveClassName.class.getSimpleName());

Nous pouvons également obtenir des types primitifs et des tableaux de noms simples. Pour les types primitifs qui seront simplement leurs noms, commeint, boolean oufloat.

Et pour les tableaux, la méthode retournerathe simple name of the type of the array followed by a pair opening and closing brackets for each dimension of the array ([]):

RetrieveClassName[] names = new RetrieveClassName[];
assertEquals("RetrieveClassName[]", names.getClass().getSimpleName());

Par conséquent, pour un tableau bidimensionnelString, appelergetSimpleName() sur sa classe renverraString[][].

Enfin, il y a le cas spécifique des classes anonymes. Calling getSimpleName() on an anonymous class will return an empty string.

3. Récupération d'autres noms

Il est maintenant temps d’examiner comment nous obtiendrions le nom, le type ou le nom canonique d’une classe. Contrairement àgetSimpleName(), ces noms visent à donner plus d'informations sur la classe.

La méthodegetCanonicalName() renvoie toujours le nom canoniqueas defined in the Java Language Specification.

Comme pour les autres méthodes, la sortie peut différer un peu en fonction des cas d'utilisation. Nous verrons ce que cela signifie pour différents types de primitifs et d'objets.

3.1. Types primitifs

Commençons par les types primitifs, car ils sont simples. For primitive types, all three methods getName(), getTypeName() and getCanonicalName() will return the same result as getSimpleName():

assertEquals("int", int.class.getName());
assertEquals("int", int.class.getTypeName());
assertEquals("int", int.class.getCanonicalName());

3.2. Types d'objet

Nous allons maintenant voir comment ces méthodes fonctionnent avec les types d'objets. Leur comportement est généralement le même:they all return the canonical name of the class.

Dans la plupart des cas, il s'agit d'un nom qualifié qui contient tous les noms simples des packages de classe ainsi que le nom simple de la classe:

assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getTypeName());
assertEquals("com.example.className.RetrieveClassName", RetrieveClassName.class.getSimpleName());

3.3. Classes intérieures

Ce que nous avons vu dans la section précédente est le comportement général de ces appels de méthode, mais il y a quelques exceptions.

Les classes intérieures en font partie. Les méthodesgetName() andgetTypeName() se comportent différemment de la méthodegetCanonicalName() pour les classes internes.

getCanonicalName() still returns the canonical name of the class, c'est-à-dire le nom canonique de la classe englobante plus le nom simple de la classe interne séparés par un point.

D'un autre côté, les méthodesgetName() andgetTypeName() renvoient à peu près la même chose queuse a dollar as the separator between the enclosing class canonical name and the inner class simple name.

Imaginons une classe interneInnerClass de nosRetrieveClassName:

public class RetrieveClassName {
    public class InnerClass {}
}

Ensuite, chaque appel dénote la classe interne d'une manière légèrement différente:

assertEquals("com.example.RetrieveClassName.InnerClass",
  RetrieveClassName.InnerClass.class.getCanonicalName());
assertEquals("com.example.RetrieveClassName$InnerClass",
  RetrieveClassName.InnerClass.class.getName());
assertEquals("com.example.RetrieveClassName$InnerClass",
  RetrieveClassName.InnerClass.class.getTypeName());

3.4. Classes Anonymes

Les classes anonymes sont une autre exception.

Comme nous l’avons déjà vu, ils n’ont pas de nom simple, maisthey also don’t have a canonical name. Par conséquent,getCanonicalName() ne renvoie rien. In opposition to getSimpleName()getCanonicalName() will return null et non une chaîne vide lorsqu'elle est appelée sur une classe anonyme.

Quant àgetName() etgetTypeName(), ils renverront lescalling class canonical name followed by a dollar and a number representing the position of the anonymous class among all anonymous classes created in the calling class.

Illustrons cela avec un exemple. Nous allons créer ici deux classes anonymes et appelergetName() sur la première etgetTypeName() fils sur la seconde, en les déclarant encom.example.Main:

assertEquals("com.example.Main$1", new RetrieveClassName() {}.getClass().getName());
assertEquals("com.example.Main$2", new RetrieveClassName() {}.getClass().getTypeName());

Nous devons noter que le deuxième appel renvoie un nom avec un nombre augmenté à sa fin, tel qu’il est appliqué à la deuxième classe anonyme.

3.5. Tableaux

Enfin, voyons comment les tableaux sont gérés par les trois méthodes ci-dessus.

Pour indiquer que nous avons affaire à des tableaux, chaque méthode mettra à jour son résultat standard. The getTypeName() and getCanonicalName() methods will append pairs of brackets to their result.

Voyons l'exemple suivant où nous appelonsgetTypeName() andgetCanonicalName() sur un tableau bidimensionnelInnerClass:

assertEquals("com.example.RetrieveClassName$InnerClass[][]",
  RetrieveClassName.InnerClass[][].class.getTypeName());
assertEquals("com.example.RetrieveClassName.InnerClass[][]",
  RetrieveClassName.InnerClass[][].class.getCanonicalName());

Notez que le premier appel utilise un dollar au lieu d'un point pour séparer la partie de classe interne du reste du nom.

Voyons maintenant comment fonctionne la méthodegetName(). Lorsqu'il est appelé sur un tableau de type primitif, il renvoiean opening bracket and a letter representing the primitive type. Vérifions cela avec l'exemple suivant, en appelant cette méthode sur un tableau d'entiers primitifs bidimensionnels:

assertEquals("[[I", int[][].class.getName());

D'autre part, lorsqu'il est appelé sur un tableau d'objets, il seraadd an opening bracket and the L letter to its standard result and finish with a semi-colon. Essayons-le sur un tableau deRetrieveClassName:

assertEquals("[Lcom.example.className.RetrieveClassName;", RetrieveClassName[].class.getName());

4. Conclusion

Dans cet article, nous avons examiné quatre méthodes pour accéder à un nom de classe en Java. Ces méthodes sont:getSimpleName(), getName(), getTypeName() etgetCanonicalName().

Nous avons appris que le premier retourne simplement le nom de code source d'une classe, tandis que les autres fournissent plus d'informations, telles que le nom du paquet, et indiquent si la classe est interne ou anonyme.

Le code de cet article se trouveover on GitHub.