ChatGPT解决这个技术问题 Extra ChatGPT

Java - 获取当前的类名?

我要做的就是获取当前的类名,java 会在我的类名末尾附加一个无用的无意义的 $1。我怎样才能摆脱它,只返回实际的类名?

String className = this.getClass().getName();
你在哪里叫这个?它来自匿名内部类吗?您能否添加更多代码来显示有关类定义的详细信息以及从何处调用此行?
所以,你想要的只是String className = getClass().getName().substring(0, getClass().getName().indexOf("$"))
如果您得到 $1,那么因为类的名称是 $1。如果您期望其他内容,请在正确的类中使用 this 而不是错误的类。

j
jesg

尝试,

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

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


实际上,不,这是行不通的。这个问题表明他有一个匿名内部类,对于这种情况,getSimpleName() 返回 ""
尽管这没有回答问题,但这篇 SO 帖子目前在 google 上的“get class name java”搜索结果中名列前茅,因此它对社区仍然有帮助。
它将返回没有包命名空间的名称。好一个!
B
Bozho

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

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

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

您可以在某些静态实用程序方法中移动它。

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


但是如果封闭类也是一个匿名内部类呢?您是否不必递归地获取封闭类,直到它返回 null,并使用您获得的最后一个非 null 类?
M
Manoj Selvin

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


事实上,确实如此。取决于。如果您尝试使用匿名类来获取您正在实现的抽象类的名称,这就是您使用的。
对于他的情况(匿名类),简单名称为空,规范名称为 null,超类为 Object。
是的,是的,不是的。我的前两个只是猜测,但是第三个是正确的。匿名类是它实现的类的子类。这就是他们工作的原因。因此,超类是抽象类。
奇怪的是你继承的类不是超类吗?处理程序不是从我的类继承,它只是一个成员
嗯...我已经测试过了,我知道匿名类的超类是抽象类。我会重新检查我的逻辑......但是当我得到有意义的结果时,我不认为是我犯了错误......
V
Vineeth Chitteti

您可以使用 this.getClass().getSimpleName(),如下所示:

import java.lang.reflect.Field;

public class Test {

    int x;
    int y;  

    public String getClassName() {

        String className = this.getClass().getSimpleName(); 
        System.out.println("Name:" + className);
        return className;
    }

    public Field[] getAttributes() {

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

        return attributes;
    }

    public static void main(String args[]) {

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

S
SoftDesigner

两个答案的组合。还打印一个方法名称:

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

J
Jason Hu

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

比方说:

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

它将达到相同的结果。此外,它实际上非常方便,因为每个类都是在编译时定义的,因此不会损坏动态性。

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

B.this.getClass().getName()

A
Ako

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

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

t
tonio

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


非匿名内部类被命名为 Outer$Inner。这将是一个匿名类。
t
trutheality

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

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

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

“hacky”方法是使用 getClassName() 获取名称并使用正则表达式删除 $1


A
Albert Khang

就我而言,我使用这个 Java 类:

private String getCurrentProcessName() {
    String processName = "";
    int pid = android.os.Process.myPid();
    
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
        if (processInfo.pid == pid) {
            processName = processInfo.processName;
            break;
        }
    }
    
    return processName;
}

T
Tigran Saluev

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

String className="";

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

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

这并没有添加任何其他答案尚未说过的任何内容。整个循环/数组问题是无关紧要的。此外,您应该研究代码格式如何处理问题/答案。
O
OneCricketeer

Reflection APIs

有几个反射 API 会返回类,但只有在已经直接或间接获得类的情况下才能访问这些 API。 Class.getSuperclass() 返回给定类的超类。类 c = javax.swing.JButton.class.getSuperclass(); javax.swing.JButton 的超类是 javax.swing.AbstractButton。 Class.getClasses() 返回属于该类成员的所有公共类、接口和枚举,包括继承的成员。类[] c = Character.class.getClasses(); Character 包含两个成员类 Character.Subset 和 Character.UnicodeBlock。 Class.getDeclaredClasses() 返回所有类接口,以及在此类中显式声明的枚举。类[] c = Character.class.getDeclaredClasses(); Character 包含两个公共成员类 Character.Subset 和 Character.UnicodeBlock 以及一个私有类 Character.CharacterCache。 Class.getDeclaringClass() java.lang.reflect.Field.getDeclaringClass() java.lang.reflect.Method.getDeclaringClass() java.lang.reflect.Constructor.getDeclaringClass() 返回声明这些成员的类。匿名类声明不会有声明类,但会有一个封闭类。导入 java.lang.reflect.Field;字段 f = System.class.getField("out");类 c = f.getDeclaringClass();字段 out 在 System.中声明。公共类 MyClass { static Object o = new Object() { public void m() {} };静态类 = o.getClass().getEnclosureClass(); o 定义的匿名类的声明类为null。 Class.getEnclosureClass() 返回类的直接封闭类。类 c = Thread.State.class().getEnclosureClass();枚举 Thread.State 的封闭类是 Thread。公共类 MyClass { static Object o = new Object() { public void m() {} };静态类 = o.getClass().getEnclosureClass();由 o 定义的匿名类被 MyClass 包围。


您是否知道您将答案发布为一个整体的代码块?语句不应格式化为代码引号...