Java - obtenir le nom de classe actuel?

272

Tout ce que j'essaie de faire, c'est d'obtenir le nom de la classe actuelle, et java ajoute un $ 1 non-sens inutile à la fin de mon nom de classe. Comment puis-je m'en débarrasser et ne renvoyer que le nom de classe réel?

String className = this.getClass().getName();
aryaxt
la source
1
Où appelez-vous cela? S'agit-il d'une classe interne anonyme? Pourriez-vous ajouter un peu plus de code qui montre des détails sur la définition de la classe et d'où cette ligne est appelée?
plainjimbo
8
Donc, tout ce que vous voulez, c'estString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow
9
Si vous obtenez $1alors, car le nom de la classe est $1. Si vous attendez autre chose, utilisez-le thisdans la bonne classe au lieu de la mauvaise.
ceving

Réponses:

248

Le «$ 1» n'est pas un «non-sens inutile». Si votre classe est anonyme, un numéro est ajouté.

Si vous ne voulez pas la classe elle-même, mais sa classe déclarante, vous pouvez utiliser getEnclosingClass() . Par exemple:

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

Vous pouvez déplacer cela dans une méthode utilitaire statique.

Mais notez que ce n'est pas le nom de la classe actuelle. La classe anonyme est une classe différente de sa classe englobante. Le cas est similaire pour les classes internes.

Bozho
la source
2
Mais que se passe-t-il si la classe englobante est également une classe interne anonyme? Ne devez-vous pas récursivement récupérer la classe englobante jusqu'à ce qu'elle revienne nullet utiliser la dernière non- nullclasse que vous avez obtenue?
Garret Wilson
231

Essayer,

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

Cela fonctionnera tant que vous ne l'utiliserez pas dans une méthode statique.

jesg
la source
1
En fait, non, cela ne fonctionnera pas. Cette question indique qu'il a une classe interne anonyme, et dans ce cas, getSimpleName () renvoie""
vikingsteve
48
Même si cela ne répond pas à la question, ce message SO est actuellement dans les premiers résultats pour "obtenir le nom de classe java" sur google, et il est donc toujours utile à la communauté.
EdgeCaseBerg
6
Il renverra le nom sans l'espace de nom du package. Bon!
Oleg Abrazhaev
31

Essayez d'utiliser ceci this.getClass().getCanonicalName()ou this.getClass().getSimpleName(). S'il s'agit d'une classe anonyme, utilisezthis.getClass().getSuperclass().getName()

MirroredFate
la source
En fait, c'est le cas. En fonction, dépendemment. Si vous essayez d'obtenir le nom de la classe abstraite que vous implémentez avec une classe anonyme, c'est ce que vous utilisez.
MirroredFate
pour son cas (classe anonyme), le nom simple est vide, le nom canconical est nul et la superclasse est Object.
Bozho
Oui, oui, non. Mes deux premiers n'étaient que des suppositions, le troisième, cependant, est correct. Une classe anonyme est une sous-classe de la classe qu'elle implémente. Voilà pourquoi ils fonctionnent. Ainsi, la superclasse est la classe abstraite.
MirroredFate
Bizarre, la super classe n'est-elle pas la classe dont vous héritez? Le gestionnaire n'hérite pas de ma classe, c'est juste un membre
aryaxt
Umm ... J'ai testé cela, et je comprends que la superclasse de la classe anonyme est la classe abstraite. Je vais revérifier ma logique ... mais comme j'obtiens le résultat qui a du sens, je ne pense pas que c'est moi qui ai fait l'erreur ....
MirroredFate
10

Vous pouvez utiliser this.getClass().getSimpleName(), comme ceci:

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();
    }
}
Karuna
la source
4

La combinaison des deux réponses. Imprime également un nom de méthode:

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

cette réponse est en retard, mais je pense qu'il existe une autre façon de le faire dans le contexte de la classe de gestionnaire anonyme.

Disons:

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

il obtiendra le même résultat. de plus, c'est en fait assez pratique puisque chaque classe est définie au moment de la compilation, donc aucune dynamicité n'est endommagée.

au-dessus de cela, si la classe est vraiment imbriquée, c'est-à-dire qu'elle Aest réellement entourée par B, la classe de B peut être facilement connue comme:

B.this.getClass().getName()
Jason Hu
la source
2

Dans votre exemple, thisfait probablement référence à une instance de classe anonyme. Java donne un nom à ces classes en ajoutant un $numberau nom de la classe englobante.

tonio
la source
2
Les classes internes non anonymes sont nommées Outer $ Inner. Ce sera une classe anonyme.
Duncan McGregor
1

Je suppose que cela se produit pour une classe anonyme. Lorsque vous créez une classe anonyme, vous créez en fait une classe qui étend la classe dont vous avez obtenu le nom.

La façon la plus «propre» d'obtenir le nom que vous voulez est:

Si votre classe est une classe interne anonyme, getSuperClass()devrait vous donner la classe à partir de laquelle elle a été créée. Si vous l'avez créé à partir d'une interface, vous êtes en quelque sorte SOL, car le mieux que vous puissiez faire est de getInterfaces()vous donner plus d'une interface.

La méthode "hacky" consiste simplement à obtenir le nom avec getClassName()et à utiliser une expression régulière pour supprimer le $1.

vérité
la source
0

Voici une variante Android, mais le même principe peut également être utilisé en Java simple.

private static final String TAG = YourClass.class.getSimpleName();
private static final String TAG = YourClass.class.getName();
Ako
la source
-3

J'ai trouvé que cela fonctionnait pour mon code, mais mon code récupère la classe d'un tableau dans une boucle for.

String className="";

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

System.out.print(className); //Use this to test it works
hransom
la source
Cela n'ajoute rien que les autres réponses n'aient déjà dit. Le problème de l'ensemble boucle / tableau n'est pas pertinent. En outre, vous devez examiner le fonctionnement du formatage du code sur les questions / réponses.
Jonathon Reinhart
-4

API de réflexion

Il existe plusieurs API Reflection qui renvoient des classes, mais elles ne sont accessibles que si une classe a déjà été obtenue directement ou indirectement.

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()

Renvoie toutes les classes, interfaces et énumérations publiques qui sont membres de la classe, y compris les membres hérités.

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

Le caractère contient deux classes membres, Character.Subset et
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

avoir une classe englobante.

        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.
arunkumar sambu
la source
2
Savez-vous que vous avez publié votre réponse comme un bloc de code monolithique total? Les déclarations ne doivent pas être formatées comme des guillemets de code ...
Massimiliano Kraus