从 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
Getting the class name from a static method in Java
提问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.so
and 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 !
希望它会有所帮助!