Java: ¿obtener el nombre de clase actual?

272

Todo lo que estoy tratando de hacer es obtener el nombre de la clase actual, y Java agrega $ 1 sin sentido inútil al final del nombre de mi clase. ¿Cómo puedo deshacerme de él y solo devolver el nombre real de la clase?

String className = this.getClass().getName();
aryaxt
fuente
1
¿A dónde llamas esto? ¿Es desde dentro de una clase interna anónima? ¿Podría agregar más código que muestre detalles sobre la definición de la clase y desde dónde se llama esta línea?
plainjimbo
8
Entonces, todo lo que quieres esString className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow
9
Si obtiene $1entonces, porque el nombre de la clase es $1. Si espera algo más, úselo thisen la clase correcta en lugar de la incorrecta.
ceving

Respuestas:

248

El "$ 1" no es un "sin sentido inútil". Si su clase es anónima, se agrega un número.

Si no desea la clase en sí misma, sino su declaración de clase, puede usarla getEnclosingClass(). Por ejemplo:

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

Puede mover eso en algún método de utilidad estática.

Pero tenga en cuenta que este no es el nombre de la clase actual. La clase anónima es una clase diferente que su clase adjunta. El caso es similar para las clases internas.

Bozho
fuente
2
Pero, ¿qué pasa si la clase adjunta también es una clase interna anónima? ¿No tiene que obtener recursivamente la clase de cierre hasta que regrese nully usar la última no nullclase que obtuvo?
Garret Wilson el
231

Tratar,

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

Esto funcionará siempre que no lo use en un método estático.

jesg
fuente
1
En realidad, no, esto no funcionará. Esta pregunta indica que tiene una clase interna anónima, y ​​para este caso, getSimpleName () regresa""
vikingsteve
48
Aunque esto no responde a la pregunta, esta publicación SO se encuentra actualmente en los mejores resultados de "get class name java" en google, por lo que sigue siendo útil para la comunidad.
EdgeCaseBerg
66
Devolverá el nombre sin espacio de nombres del paquete. Bueno uno!
Oleg Abrazhaev
31

Intenta usar esto this.getClass().getCanonicalName()o this.getClass().getSimpleName(). Si es una clase anónima, usethis.getClass().getSuperclass().getName()

Destino Espejado
fuente
En realidad lo hace. Dependiente. Si está intentando obtener el nombre de la clase abstracta que está implementando con una clase anónima, esto es lo que usa.
MirroredFate
para su caso (clase anónima), el nombre simple está vacío, el nombre cancónico es nulo y la superclase es Object.
Bozho
Si si, no. Mis dos primeros fueron solo conjeturas, el tercero, sin embargo, es correcto. Una clase anónima es una subclase de la clase que implementa. Por eso trabajan. Por lo tanto, la superclase es la clase abstracta.
MirroredFate
¿Extraño no es la superclase de la clase de la que estás heredando? Handler no está heredando forma de mi clase, es sólo un miembro
aryaxt
Umm ... He probado esto, y entiendo que la superclase de la clase anónima es la clase abstracta. Volveré a verificar mi lógica ... pero a medida que obtengo el resultado que tiene sentido, no creo que haya sido yo quien haya cometido el error ...
MirroredFate
10

Puedes usar this.getClass().getSimpleName(), así:

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

La combinación de ambas respuestas. También imprime un nombre de método:

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

esta respuesta llega tarde, pero creo que hay otra forma de hacerlo en el contexto de la clase de controlador anónimo.

digamos:

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

logrará el mismo resultado. Además, en realidad es bastante conveniente ya que cada clase se define en tiempo de compilación, por lo que no se daña la dinámica.

por encima de eso, si la clase está realmente anidada, es decir, en Arealidad está encerrada por B, la clase de B puede ser fácilmente conocida como:

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

En su ejemplo, thisprobablemente se refiere a una instancia de clase anónima. Java le da un nombre a esas clases agregando un $numberal nombre de la clase adjunta.

tonio
fuente
2
Las clases internas no anónimas se denominan Outer $ Inner. Esta será una clase anónima.
Duncan McGregor
1

Supongo que esto está sucediendo para una clase anónima. Cuando crea una clase anónima, en realidad crea una clase que extiende la clase cuyo nombre obtuvo.

La forma "más limpia" de obtener el nombre que desea es:

Si su clase es una clase interna anónima, getSuperClass()debería darle la clase a partir de la cual se creó. Si lo creó desde una interfaz, entonces es una especie de SOL porque lo mejor que puede hacer es lo getInterfaces()que le puede proporcionar más de una interfaz.

La forma "hacky" es simplemente obtener el nombre getClassName()y usar una expresión regular para soltar el $1.

la verdad
fuente
0

Aquí hay una variante de Android, pero también se puede usar el mismo principio en Java simple.

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

He encontrado que esto funciona para mi código, sin embargo, mi código está sacando la clase de una matriz dentro de un bucle for.

String className="";

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

System.out.print(className); //Use this to test it works
hransom
fuente
Esto no agrega nada que ninguna de las otras respuestas ya haya dicho. Todo el problema del loop / array es irrelevante. Además, debe analizar cómo funciona el formato de código en las preguntas / respuestas.
Jonathon Reinhart
-4

API de reflexión

Existen varias API de Reflection que devuelven clases, pero solo se puede acceder a ellas si ya se ha obtenido una Clase, ya sea directa o indirectamente.

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

Devuelve todas las clases públicas, interfaces y enumeraciones que son miembros de la clase, incluidos los miembros heredados.

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

Character contiene dos clases miembro Character.Subset y
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

tener una clase de cierre.

        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
fuente
2
¿Sabe que publicó su respuesta como un bloque de código monolítico total? Las declaraciones no deben formatearse como citas de código ...
Massimiliano Kraus