从 Java 中的静态方法获取类名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/936684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:17:43  来源:igfitidea点击:

Getting the class name from a static method in Java

javastatic

提问by Miles D

How can one get the name of the class from a static method in that class. For example

如何从该类中的静态方法中获取该类的名称。例如

public class MyClass {
    public static String getClassName() {
        String name = ????; // what goes here so the string "MyClass" is returned
        return name;
    }
}

To put it in context, I actually want to return the class name as part of a message in an exception.

把它放在上下文中,我实际上想将类名作为异常消息的一部分返回。

采纳答案by toolkit

In order to support refactoring correctly (rename class), then you should use either:

为了正确支持重构(重命名类),您应该使用:

 MyClass.class.getName(); // full name with package

or (thanks to @James Van Huis):

或(感谢@James Van Huis):

 MyClass.class.getSimpleName(); // class name and no more

回答by James Van Huis

If you want the entire package name with it, call:

如果你想要整个包名,请调用:

String name = MyClass.class.getCanonicalName();

If you only want the last element, call:

如果您只想要最后一个元素,请调用:

String name = MyClass.class.getSimpleName();

回答by Tom Hawtin - tackline

Do what toolkit says. Do not do anything like this:

按照工具包说的去做。不要做这样的事情:

return new Object() { }.getClass().getEnclosingClass();

回答by Christoffer

Abuse the SecurityManager

滥用安全管理器

System.getSecurityManager().getClassContext()[0].getName();

Or, if not set, use an inner class that extends it (example below shamefully copied from Real's HowTo):

或者,如果未设置,则使用扩展它的内部类(下面的示例可耻地从Real 的 HowTo复制而来):

public static class CurrentClassGetter extends SecurityManager {
    public String getClassName() {
        return getClassContext()[1].getName(); 
    }
}

回答by count ludwig

I use this to init the Log4j Logger at the top of my classes (or annotate).

我用它来初始化我的类(或注释)顶部的 Log4j Logger。

PRO: Throwable is already loaded and you might save resources by not using the "IO heavy" SecurityManager.

PRO:Throwable 已加载,您可以通过不使用“IO 重”SecurityManager 来节省资源。

CON: Some question as to whether this will work for all JVMs.

缺点:关于这是否适用于所有 JVM 的一些问题。

// Log4j . Logger --- Get class name in static context by creating an anonymous Throwable and 
// getting the top of its stack-trace. 
// NOTE you must use: getClassName() because getClass() just returns StackTraceElement.class 
static final Logger logger = Logger.getLogger(new Throwable() .getStackTrace()[0].getClassName()); 

回答by Keksi

This instruction works fine:

此指令工作正常:

Thread.currentThread().getStackTrace()[1].getClassName();

回答by lifelongcoug

You could do something really sweet by using JNI like this:

你可以像这样使用 JNI 来做一些非常棒的事情:

MyObject.java:

我的对象.java:

public class MyObject
{
    static
    {
        System.loadLibrary( "classname" );
    }

    public static native String getClassName();

    public static void main( String[] args )
    {
        System.out.println( getClassName() );
    }
}

then:

然后:

javac MyObject.java
javah -jni MyObject

then:

然后:

MyObject.c:

我的对象.c:

#include "MyObject.h"

JNIEXPORT jstring JNICALL Java_MyObject_getClassName( JNIEnv *env, jclass cls )
{
    jclass javaLangClass = (*env)->FindClass( env, "java/lang/Class" );
    jmethodID getName = (*env)->GetMethodID( env, javaLangClass, "getName",
        "()Ljava/lang/String;" );
    return (*env)->CallObjectMethod( env, cls, getName );
}

Then compile the C up into a shared library called libclassname.soand run the java!

然后将 C 编译成一个名为的共享库libclassname.so并运行 java!

*chuckle

*轻笑

回答by Sergey Ushakov

Verbatim use of caller's class like MyClass.class.getName()actually does the job, but is prone to copy/paste errors if you propagate this code to numerous classes/subclasses where you need this class name.

逐字使用调用者的类就像MyClass.class.getName()实际完成工作一样,但如果将此代码传播到需要此类名称的众多类/子类,则容易出现复制/粘贴错误。

And Tom Hawtin's recipeis in fact not bad, one just needs to cook it the right way :)

汤姆Hawtin的食谱其实不差,一个只需要做饭正确的方式:)

In case you have a base class with a static method that may be called from subclasses, and this static method needs to know the actual caller's class, this may be achieved like the following:

如果您有一个带有静态方法的基类,可以从子类调用,并且这个静态方法需要知道实际调用者的类,这可以像下面这样实现:

class BaseClass {
  static sharedStaticMethod (String callerClassName, Object... otherArgs) {
    useCallerClassNameAsYouWish (callerClassName);
    // and direct use of 'new Object() { }.getClass().getEnclosingClass().getName()'
    // instead of 'callerClassName' is not going to help here,
    // as it returns "BaseClass"
  }
}

class SubClass1 extends BaseClass {
  static someSubclassStaticMethod () {
    // this call of the shared method is prone to copy/paste errors
    sharedStaticMethod (SubClass1.class.getName(),
                        other_arguments);
    // and this call is safe to copy/paste
    sharedStaticMethod (new Object() { }.getClass().getEnclosingClass().getName(),
                        other_arguments);
  }
}

回答by avalori

A refactoring-safe, cut&paste-safe solution that avoids the definition of ad-hoc classes below.

一种重构安全、剪切和粘贴安全的解决方案,它避免了下面对特定类的定义。

Write a static method that recover the class name having care to include the class name in the method name:

编写一个恢复类名的静态方法,注意在方法名中包含类名:

private static String getMyClassName(){
  return MyClass.class.getName();
}

then recall it in your static method:

然后在您的静态方法中调用它:

public static void myMethod(){
  Tracer.debug(getMyClassName(), "message");
}

Refactoring safety is given by avoiding the use of strings, cut&paste safety is granted because if you cut&paste the caller method you won't find the getMyClassName() in the target "MyClass2" class, so you will be forced to redefine and update it.

通过避免使用字符串来提供重构安全性,授予剪切和粘贴安全性,因为如果您剪切并粘贴调用者方法,您将不会在目标“MyClass2”类中找到 getMyClassName(),因此您将被迫重新定义和更新它。

回答by phaderer

I needed the class name in the static methods of multiple classes so I implemented a JavaUtil Class with the following method :

我需要多个类的静态方法中的类名,所以我使用以下方法实现了一个 JavaUtil 类:

public static String getClassName() {
    String className = Thread.currentThread().getStackTrace()[2].getClassName();
    int lastIndex = className.lastIndexOf('.');
    return className.substring(lastIndex + 1);
}

Hope it will help !

希望它会有所帮助!