Recupero di un nome di classe in Java

1. Panoramica

In questo tutorial, impareremo quattro modi per recuperare il nome di una classe dai metodi sull'API della classe : getSimpleName (), getName (), getTypeName () e getCanonicalName ().

Questi metodi possono creare confusione a causa dei loro nomi simili e dei loro Javadoc piuttosto vaghi. Hanno anche alcune sfumature quando si tratta di tipi primitivi, tipi di oggetto, classi interne o anonime e array.

2. Recupero del nome semplice

Cominciamo con il metodo getSimpleName () .

In Java esistono due tipi di nomi: semplici e qualificati . Un nome semplice è costituito da un identificatore univoco mentre un nome completo è una sequenza di nomi semplici separati da punti.

Come suggerisce il nome, getSimpleName () restituisce il nome semplice della classe sottostante, che è il nome che le è stato dato nel codice sorgente .

Immaginiamo la seguente classe:

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

Il suo nome semplice sarebbe RetrieveClassName :

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

Possiamo anche ottenere tipi primitivi e nomi semplici di array. Per i tipi primitivi che saranno semplicemente i loro nomi, come int, boolean o float .

E per gli array, il metodo restituirà il semplice nome del tipo di array seguito da una coppia di parentesi graffe di apertura e chiusura per ogni dimensione dell'array ([]) :

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

Di conseguenza, per un array String bidimensionale , la chiamata a getSimpleName () sulla sua classe restituirà String [] [] .

Infine, c'è il caso specifico delle classi anonime. La chiamata a getSimpleName () su una classe anonima restituirà una stringa vuota.

3. Recupero di altri nomi

Ora è il momento di dare un'occhiata a come ottenere il nome di una classe, il nome del tipo o il nome canonico. A differenza di getSimpleName () , questi nomi mirano a fornire maggiori informazioni sulla classe.

Il metodo getCanonicalName () restituisce sempre il nome canonico come definito nella specifica del linguaggio Java.

Per quanto riguarda gli altri metodi, l'output può differire leggermente a seconda dei casi d'uso. Vedremo cosa significa per diversi tipi di primitivi e oggetti.

3.1. Tipi primitivi

Cominciamo con i tipi primitivi, poiché sono semplici. Per i tipi primitivi, tutti e tre i metodi getName (), getTypeName () e getCanonicalName () restituiranno lo stesso risultato di getSimpleName () :

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

3.2. Tipi di oggetti

Vedremo ora come funzionano questi metodi con i tipi di oggetto. Il loro comportamento è generalmente lo stesso: restituiscono tutti il ​​nome canonico della classe .

Nella maggior parte dei casi, questo è un nome completo che contiene tutti i nomi semplici dei pacchetti di classe oltre al nome semplice della classe:

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

3.3. Classi interne

Quello che abbiamo visto nella sezione precedente è il comportamento generale di queste chiamate di metodo, ma ci sono alcune eccezioni.

Le classi interne sono una di queste. I metodi getName () e getTypeName () si comportano in modo diverso dal metodo getCanonicalName () per le classi interne.

getCanonicalName () restituisce ancora il nome canonico della classe , ovvero il nome canonico della classe che la racchiude più il nome semplice della classe interna separato da un punto.

D'altra parte, i metodi getName () e getTypeName () restituiscono più o meno lo stesso, ma usano un dollaro come separatore tra il nome canonico della classe che lo racchiude e il nome semplice della classe interna .

Immaginiamo una classe interna InnerClass del nostro RetrieveClassName :

public class RetrieveClassName { public class InnerClass {} }

Quindi ogni chiamata denota la classe interna in un modo leggermente diverso:

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

3.4. Classi anonime

Le classi anonime sono un'altra eccezione.

Come abbiamo già visto, non hanno un nome semplice, ma non hanno nemmeno un nome canonico . Pertanto, getCanonicalName () non restituisce nulla. In opposizione a getSimpleName () , getCanonicalName () restituirà null e non una stringa vuota quando viene chiamato su una classe anonima.

Per quanto riguarda getName () e getTypeName () restituiranno il nome canonico della classe chiamante seguito da un dollaro e un numero che rappresenta la posizione della classe anonima tra tutte le classi anonime create nella classe chiamante .

Illustriamolo con un esempio. Creeremo qui due classi anonime e chiameremo getName () sulla prima e getTypeName () sulla seconda, dichiarandole in com.baeldung.Main :

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

Dobbiamo notare che la seconda chiamata restituisce un nome con un numero maggiore alla fine, poiché viene applicato alla seconda classe anonima.

3.5. Arrays

Infine, vediamo come vengono gestiti gli array con i tre metodi precedenti.

Per indicare che abbiamo a che fare con gli array, ogni metodo aggiornerà il suo risultato standard. I metodi getTypeName () e getCanonicalName () aggiungeranno coppie di parentesi al loro risultato.

Vediamo il seguente esempio in cui chiamiamo getTypeName () e getCanonicalName () su un array bidimensionale InnerClass :

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

Nota come la prima chiamata utilizza un dollaro invece di un punto per separare la parte della classe interna dal resto del nome.

Vediamo ora come funziona il metodo getName () . Quando viene chiamato su un array di tipo primitivo, restituirà una parentesi aperta e una lettera che rappresenta il tipo primitivo .Controlliamolo con il seguente esempio, chiamando quel metodo su un array di interi primitivi bidimensionali:

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

D'altra parte, quando viene chiamato su un array di oggetti, aggiungerà una parentesi di apertura e la lettera L al suo risultato standard e terminerà con un punto e virgola . Proviamolo su un array di RetrieveClassName :

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

4. Conclusione

In questo articolo, abbiamo esaminato quattro metodi per accedere a un nome di classe in Java. Questi metodi sono: getSimpleName (), getName (), getTypeName () e getCanonicalName () .

Abbiamo appreso che il primo restituisce solo il nome del codice sorgente di una classe mentre gli altri forniscono ulteriori informazioni come il nome del pacchetto e un'indicazione se la classe è interna o anonima.

Il codice di questo articolo può essere trovato su GitHub.