Java - obtém o nome da classe atual?

271

Tudo o que estou tentando fazer é obter o nome da classe atual e o java acrescenta um inútil e inútil $ 1 ao final do nome da minha classe. Como posso me livrar dele e retornar apenas o nome da classe real?

String className = this.getClass().getName();
aryaxt
fonte
1
Para onde você está chamando isso? É de dentro de uma classe interna anônima? Você poderia adicionar um pouco mais de código que mostra detalhes sobre a definição da classe e de onde essa linha está sendo chamada?
precisa saber é o seguinte
8
Então, tudo que você quer éString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow
9
Se você receber $1, porque o nome da classe é $1. Se você espera algo mais, use thisna classe certa em vez da errada.
ceving 26/09/14

Respostas:

247

O "$ 1" não é "inútil sem sentido". Se sua turma for anônima, um número será anexado.

Se você não quiser a classe em si, mas a classe declarante, poderá usar getEnclosingClass(). Por exemplo:

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

Você pode mover isso em algum método de utilitário estático.

Mas observe que esse não é o nome da classe atual. A classe anônima é diferente da classe envolvente. O caso é semelhante para classes internas.

Bozho
fonte
2
Mas e se a classe envolvente também for uma classe interna anônima? Você não precisa recursivamente obter a classe anexa até que ela retorne nulle usar a última não- nullclasse que você obteve?
Garret Wilson
231

Experimentar,

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

Isso funcionará desde que você não o use em um método estático.

jesg
fonte
1
Na verdade, não, isso não vai funcionar. Esta pergunta indica que ele tem uma classe interna anônima e, neste caso, getSimpleName () retorna""
vikingsteve
48
Mesmo que isso não responda à pergunta, atualmente esta postagem do SO está nos principais resultados para "obter o nome da classe java" no google e, portanto, ainda é útil para a comunidade.
EdgeCaseBerg
6
Ele retornará o nome sem o espaço para nome do pacote. Um bom!
precisa saber é o seguinte
31

Tente usar este this.getClass().getCanonicalName()ou this.getClass().getSimpleName(). Se for uma classe anônima, usethis.getClass().getSuperclass().getName()

MirroredFate
fonte
Na verdade, sim. Dependendo. Se você está tentando obter o nome da classe abstrata que está implementando com uma classe anônima, é isso que você usa.
precisa
para seu caso (classe anônima), o nome simples está vazio, o nome canônico é nulo e a superclasse é Object.
Bozho
Sim sim não Meus dois primeiros foram apenas suposições, o terceiro, no entanto, está correto. Uma classe anônima é uma subclasse da classe que implementa. É por isso que eles trabalham. Assim, a superclasse é a classe abstrata.
precisa
Estranho não é a super classe da classe que você está herdando? Handler não está herdando forma minha classe, é apenas um membro
aryaxt
Umm ... Eu testei isso, e entendi que a superclasse da classe anônima é a classe abstrata. Vou verificar novamente a minha lógica ... mas como eu estou ficando o resultado que faz sentido, eu não acho que isso me que cometeu o erro é ....
MirroredFate
10

Você pode usar this.getClass().getSimpleName(), assim:

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
fonte
4

A combinação de ambas as respostas. Também imprime um nome de método:

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

essa resposta está atrasada, mas acho que há outra maneira de fazer isso no contexto da classe de manipulador anônimo.

Digamos:

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

alcançará o mesmo resultado. Além disso, é realmente bastante conveniente, pois todas as classes são definidas em tempo de compilação, portanto, nenhuma dinamicidade é danificada.

acima disso, se a classe é realmente aninhada, ou seja, Ana verdade é delimitada por B, a classe B pode ser facilmente conhecida como:

B.this.getClass().getName()
Jason Hu
fonte
2

No seu exemplo, thisprovavelmente se refere a uma instância de classe anônima. Java atribui um nome a essas classes anexando $numbera ao nome da classe envolvente.

tonio
fonte
2
Classes internas não anônimas são denominadas Outer $ Inner. Esta será uma classe anônima.
Duncan McGregor
1

Estou assumindo que isso está acontecendo para uma classe anônima. Quando você cria uma classe anônima, na verdade você cria uma classe que estende a classe cujo nome você recebeu.

A maneira "mais limpa" de obter o nome desejado é:

Se sua classe é uma classe interna anônima, getSuperClass()você deve fornecer a classe da qual ela foi criada. Se você o criou a partir de uma interface, é uma espécie de SOL, porque o melhor que você pode fazer égetInterfaces() que pode lhe dar mais de uma interface.

A maneira "hacky" é apenas pegar o nome getClassName()e usar um regex para soltar o $1.

verdade
fonte
0

Aqui está uma variante do Android, mas o mesmo princípio também pode ser usado em Java comum.

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

Descobri que isso funciona para o meu código, no entanto, meu código está obtendo a classe de uma matriz dentro de um loop for.

String className="";

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

System.out.print(className); //Use this to test it works
hransom
fonte
Isso não adiciona nada que nenhuma das outras respostas ainda não tenha dito. Todo o problema de loop / matriz é irrelevante. Além disso, você deve examinar como a formatação do código funciona nas perguntas / respostas.
Jonathon Reinhart
-4

APIs de reflexão

Existem várias APIs de reflexão que retornam classes, mas elas só podem ser acessadas se uma classe já tiver sido obtida direta ou indiretamente.

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

Retorna todas as classes públicas, interfaces e enumerações que são membros da classe, incluindo membros herdados.

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

Character contém duas classes de membros 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

tem uma classe anexa.

        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
fonte
2
Você está ciente de que postou sua resposta como um bloco de código monolítico total? As instruções não devem ser formatadas como aspas ...
Massimiliano Kraus 13/03