Java-获取当前的类名?


271

我要做的就是获取当前的类名,并且java在类名的末尾附加了一个无用的废话$ 1。如何摆脱它,只返回实际的类名?

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

1
你在哪里叫这个?它来自匿名内部类吗?您是否可以添加更多代码,以显示有关类的定义以及从何处调用此行的详细信息?
plainjimbo 2011年

8
所以,您想要的只是String className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
josh.trow 2011年

9
如果得到的$1话,因为该类的名称是$1。如果您还有其他期望,请使用this正确的类而不是错误的类。
ceving

Answers:


247

“ $ 1”不是“无用的废话”。如果您的班级是匿名的,则会附加一个数字。

如果您不想要类本身,而是想要其声明类,则可以使用getEnclosingClass()。例如:

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

您可以将其移动到某些静态实用程序方法中。

但是请注意,这不是当前的类名。匿名类与其封闭类是不同的类。内部类的情况与此类似。


2
但是,如果封闭类也是匿名内部类,该怎么办?您是否需要递归地获取封闭类,直到它返回null,并使用null您得到的最后一个非类?
Garret Wilson

231

尝试,

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

只要您不以静态方法使用它,它将起作用。


1
实际上,这不行。这个问题表明他有一个匿名内部类,在这种情况下,""
getSimpleName

48
即使这不能回答问题,此SO帖子目前仍在Google上“获取类名java”的最佳搜索结果中,因此对社区仍然有帮助。
EdgeCaseBerg 2014年

6
它将返回没有包名称空间的名称。好一个!
Oleg Abrazhaev

31

尝试使用此 this.getClass().getCanonicalName()this.getClass().getSimpleName()。如果是匿名类,请使用this.getClass().getSuperclass().getName()


实际上,确实如此。视情况而定。如果试图获取要使用匿名类实现的抽象类的名称,则使用此名称。
MirroredFate

对于他的情况(匿名类),简单名称为空,圆锥形名称为null,超类为Object。
2011年

是的,是的,不是。我的前两个只是猜测,而第三个是正确的。匿名类是其实现的类的子类。这就是为什么他们工作。因此,超类是抽象类。
MirroredFate

奇怪的不是您继承的类的超类吗?处理程序不是从我的类继承的,它只是一个成员
aryaxt

嗯...我已经测试过了,我知道匿名类的超类是抽象类。我将重新检查自己的逻辑……但是,当我得到有意义的结果时,我不认为是我犯了错误。……
MirroredFate

10

您可以这样使用this.getClass().getSimpleName()

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

两种答案的结合。同时显示方法名称:

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

3

这个答案来晚了,但是我认为在匿名处理程序类的上下文中还有另一种方法可以做到这一点。

比方说:

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

它会达到相同的结果。此外,由于每个类都是在编译时定义的,因此实际上很方便,因此不会破坏动态性。

除此之外,如果该类确实是嵌套的,即A实际上被包围B,则B的类可以很容易地称为:

B.this.getClass().getName()

2

在您的示例中,this可能是指一个匿名类实例。Java通过将a附加$number到封闭类的名称中来为这些类命名。


2
非匿名内部类称为Outer $ Inner。这将是一个匿名类。
Duncan McGregor

1

我假设这是在匿名类中发生的。当您创建匿名类时,实际上是在创建一个类,该类扩展了您所用的名称。

获得所需名称的“更清洁”方法是:

如果您的课程是匿名内部课程,getSuperClass()则应为您提供创建该课程的课程。如果您是从某个界面创建它的,那么您就不是SOL,因为您能做的最好的事情就是getInterfaces()可能为您提供多个界面。

“ hacky”方式是仅getClassName()使用来获取名称,然后使用正则表达式删除$1


0

这是一个Android变体,但是相同的原理也可以在纯Java中使用。

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

-3

我发现这适用于我的代码,但是我的代码是将类从for循环内的数组中取出。

String className="";

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

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

这不会添加任何其他答案尚未说过的内容。整个循环/数组问题无关紧要。此外,您还应该研究代码格式化对问题/答案的工作方式。
乔纳森·莱因哈特

-4

反射API

有几种反射API返回类,但是只有在已经直接或间接获得类的情况下,才可以访问这些API。

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

返回属于该类成员的所有公共类,接口和枚举,包括继承的成员。

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

字符包含两个成员类Character.Subset和
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

有一个封闭的类。

        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
您是否知道您以完整的整体代码块形式发布了答案?语句不应该格式化为代码引号...
Massimiliano Kraus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.