Java: ottieni il nome della classe corrente?


272

Tutto quello che sto cercando di fare è ottenere il nome della classe corrente e java aggiunge un inutile non senso $ 1 alla fine del mio nome di classe. Come posso liberarmene e restituire solo il nome della classe attuale?

String className = this.getClass().getName();

1
Dove lo chiami? Proviene da una classe interna anonima? Potresti aggiungere altro codice che mostri dettagli sulla definizione della classe e da dove viene chiamata questa linea?
plainjimbo,

8
Quindi, tutto ciò che vuoi èString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow,

9
Se ottieni $1allora, perché il nome della classe è $1. Se ti aspetti qualcos'altro, usa thisla classe giusta anziché quella sbagliata.
ceving il

Risposte:


248

"$ 1" non è "inutile non-senso". Se la tua classe è anonima, viene aggiunto un numero.

Se non vuoi la classe stessa, ma la sua classe dichiarante, puoi usare getEnclosingClass(). Per esempio:

Class<?> enclosingClass = getClass().getEnclosingClass();
if (enclosingClass != null) {
  System.out.println(enclosingClass.getName());
} else {
  System.out.println(getClass().getName());
}

Puoi spostarlo in qualche metodo di utilità statica.

Ma nota che questo non è il nome della classe corrente. La classe anonima è diversa dalla classe che la racchiude. Il caso è simile per le classi interne.


2
Ma cosa succede se la classe che racchiude è anche una classe interna anonima? Non è necessario ottenere ricorsivamente la classe che la racchiude fino a quando non ritorna nulle utilizzare l'ultima non- nullclasse ottenuta?
Garret Wilson,

231

Provare,

String className = this.getClass().getSimpleName();

Funzionerà finché non lo usi in un metodo statico.


1
In realtà, no, questo non funzionerà. Questa domanda indica che ha una classe interna anonima e, in questo caso, restituisce getSimpleName ()""
vikingsteve

48
Anche se questo non risponde alla domanda, questo post SO è attualmente tra i migliori risultati di "get class name java" su google, e quindi è ancora utile per la community.
EdgeCaseBerg,

6
Restituirà il nome senza spazio dei nomi dei pacchetti. Buona!
Oleg Abrazhaev,

31

Prova a usare questo this.getClass().getCanonicalName()o this.getClass().getSimpleName(). Se si tratta di una classe anonima, utilizzarethis.getClass().getSuperclass().getName()


In realtà, lo fa. Dipendente. Se stai cercando di ottenere il nome della classe astratta che stai implementando con una classe anonima, questo è quello che usi.
MirroredFate

per il suo caso (classe anonima), il nome semplice è vuoto, il nome canconical è nullo e la superclasse è Object.
Bozho,

Sì, sì, no. I miei primi due erano solo ipotesi, il terzo, tuttavia, è corretto. Una classe anonima è una sottoclasse della classe che implementa. Ecco perché funzionano. Pertanto, la superclasse è la classe astratta.
MirroredFate

Strano non è la super classe da cui stai ereditando? Handler non è ereditato dalla mia classe, è solo un membro
circa il

Umm ... l'ho provato e ho capito che la superclasse della classe anonima è la classe astratta. Ricontrollerò la mia logica ... ma mentre sto ottenendo il risultato che ha un senso, non penso che sono io a aver commesso l'errore ....
MirroredFate

10

Puoi usare this.getClass().getSimpleName(), in questo modo:

import java.lang.reflect.Field;

public class Test {

    int x;
    int y;  

    public void getClassName() {
        String className = this.getClass().getSimpleName(); 
        System.out.println("Name:" + className);
    }

    public void getAttributes() {
        Field[] attributes = this.getClass().getDeclaredFields();   
        for(int i = 0; i < attributes.length; i++) {
            System.out.println("Declared Fields" + attributes[i]);    
        }
    }

    public static void main(String args[]) {

        Test t = new Test();
        t.getClassName();
        t.getAttributes();
    }
}

4

La combinazione di entrambe le risposte. Stampa anche il nome di un metodo:

Class thisClass = new Object(){}.getClass();
String className = thisClass.getEnclosingClass().getSimpleName();
String methodName = thisClass.getEnclosingMethod().getName();
Log.d("app", className + ":" + methodName);

3

questa risposta è in ritardo, ma penso che ci sia un altro modo per farlo nel contesto di una classe di gestori anonimi.

diciamo:

class A {
    void foo() {
        obj.addHandler(new Handler() {
            void bar() {
                String className=A.this.getClass().getName();
                // ...
            }
        });
    }
}

otterrà lo stesso risultato. inoltre, in realtà è abbastanza comodo poiché ogni classe è definita al momento della compilazione, quindi nessuna dinamica è danneggiata.

sopra quello, se la classe è veramente nidificata, cioè Aè effettivamente racchiusa da B, la classe di B può essere facilmente conosciuta come:

B.this.getClass().getName()

2

Nel tuo esempio, thisprobabilmente si riferisce a un'istanza di classe anonima. Java dà un nome a quelle classi aggiungendo $numbera al nome della classe che la racchiude.


2
Le classi interne non anonime sono denominate Outer $ Inner. Questa sarà una lezione anonima.
Duncan McGregor,

1

Suppongo che ciò accada per una classe anonima. Quando crei una classe anonima, crei effettivamente una classe che estende la classe di cui hai il nome.

Il modo "più pulito" per ottenere il nome desiderato è:

Se la tua classe è una classe interna anonima, getSuperClass()dovresti fornirti la classe da cui è stata creata. Se l'hai creato da un'interfaccia di quanto sei una specie di SOL perché il meglio che puoi fare è getInterfaces()che potrebbe darti più di un'interfaccia.

Il modo "hacky" è semplicemente ottenere il nome getClassName()e usare una regex per rilasciare il file $1.


0

Ecco una variante di Android, ma lo stesso principio può essere usato anche in Java.

private static final String TAG = YourClass.class.getSimpleName();
private static final String TAG = YourClass.class.getName();

-3

Ho trovato che questo funziona per il mio codice, tuttavia il mio codice sta estraendo la classe da un array all'interno di un ciclo for.

String className="";

className = list[i].getClass().getCanonicalName();

System.out.print(className); //Use this to test it works

Questo non aggiunge nulla che nessuna delle altre risposte non abbia già detto. L'intero problema loop / array è irrilevante. Inoltre, dovresti esaminare come funziona la formattazione del codice su domande / risposte.
Jonathon Reinhart,

-4

API di riflessione

Esistono diverse API Reflection che restituiscono classi, ma è possibile accedervi solo se una Classe è già stata ottenuta direttamente o indirettamente.

Class.getSuperclass()
     Returns the super class for the given class.

        Class c = javax.swing.JButton.class.getSuperclass();
        The super class of javax.swing.JButton is javax.swing.AbstractButton.

        Class.getClasses()

Restituisce tutte le classi, le interfacce e le enumerazioni pubbliche che sono membri della classe inclusi i membri ereditati.

        Class<?>[] c = Character.class.getClasses();

Character contiene due classi membro Character.Subset e
Character.UnicodeBlock.

        Class.getDeclaredClasses()
         Returns all of the classes interfaces, and enums that are explicitly declared in this class.

        Class<?>[] c = Character.class.getDeclaredClasses();
     Character contains two public member classes Character.Subset and Character.UnicodeBlock and one private class

Character.CharacterCache.

        Class.getDeclaringClass()
        java.lang.reflect.Field.getDeclaringClass()
        java.lang.reflect.Method.getDeclaringClass()
        java.lang.reflect.Constructor.getDeclaringClass()
     Returns the Class in which these members were declared. Anonymous Class Declarations will not have a declaring class but will

avere una classe chiusa.

        import java.lang.reflect.Field;

            Field f = System.class.getField("out");
            Class c = f.getDeclaringClass();
            The field out is declared in System.
            public class MyClass {
                static Object o = new Object() {
                    public void m() {} 
                };
                static Class<c> = o.getClass().getEnclosingClass();
            }

     The declaring class of the anonymous class defined by o is null.

    Class.getEnclosingClass()
     Returns the immediately enclosing class of the class.

    Class c = Thread.State.class().getEnclosingClass();
     The enclosing class of the enum Thread.State is Thread.

    public class MyClass {
        static Object o = new Object() { 
            public void m() {} 
        };
        static Class<c> = o.getClass().getEnclosingClass();
    }
     The anonymous class defined by o is enclosed by MyClass.

2
Sei consapevole di aver pubblicato la tua risposta come un blocco di codice monolitico totale? Le dichiarazioni non devono essere formattate come virgolette ...
Massimiliano Kraus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.