如何从该类的静态方法中获取该类的名称。例如
public class MyClass {
public static String getClassName() {
String name = ????; // what goes here so the string "MyClass" is returned
return name;
}
}
为了把它放在上下文中,我实际上想在异常中返回类名作为消息的一部分。
如何从该类的静态方法中获取该类的名称。例如
public class MyClass {
public static String getClassName() {
String name = ????; // what goes here so the string "MyClass" is returned
return name;
}
}
为了把它放在上下文中,我实际上想在异常中返回类名作为消息的一部分。
当前回答
一种重构安全、剪切和粘贴安全的解决方案,避免了下面定义的临时类。
写一个恢复类名的静态方法,注意在方法名中包含类名:
private static String getMyClassName(){
return MyClass.class.getName();
}
然后在你的静态方法中召回它:
public static void myMethod(){
Tracer.debug(getMyClassName(), "message");
}
重构安全性是通过避免使用字符串来实现的,剪切和粘贴安全性是被授予的,因为如果你剪切和粘贴调用者方法,你将在目标“MyClass2”类中找不到getMyClassName(),所以你将被迫重新定义和更新它。
其他回答
像MyClass.class.getName()这样的调用者类的逐字使用实际上完成了这项工作,但是如果您将此代码传播到许多需要此类名的类/子类中,则容易产生复制/粘贴错误。
汤姆·霍丁的食谱其实不错,你只需要用正确的方式烹饪就行了:)
如果你有一个带有静态方法的基类,这个静态方法可以从子类调用,并且这个静态方法需要知道实际调用者的类,这可以像下面这样实现:
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);
}
}
如果你想要整个包的名称,调用:
String name = MyClass.class.getCanonicalName();
如果你只想要最后一个元素,调用:
String name = MyClass.class.getSimpleName();
因为问题是' this.class '而不是' ClassName.class ' ?被标记为这个的重复(这是有争议的,因为这个问题是关于类而不是类名),我在这里发布答案:
class MyService {
private static Class thisClass = MyService.class;
// or:
//private static Class thisClass = new Object() { }.getClass().getEnclosingClass();
...
static void startService(Context context) {
Intent i = new Intent(context, thisClass);
context.startService(i);
}
}
将thisClass定义为private很重要,因为: 1)它不能被继承:派生类必须要么定义自己的thisClass,要么产生错误消息 2)其他类的引用应该使用ClassName.class而不是ClassName.thisClass。
定义了thisClass后,对类名的访问变为:
thisClass.getName()
滥用SecurityManager
System.getSecurityManager().getClassContext()[0].getName();
或者,如果没有设置,使用一个内部类来扩展它(下面的例子可耻地复制自Real的HowTo):
public static class CurrentClassGetter extends SecurityManager {
public String getClassName() {
return getClassContext()[1].getName();
}
}
我使用它在类的顶部初始化Log4j Logger(或注释)。
优点:Throwable已经加载,你可能会节省资源,不使用“IO重型”安全管理器。
反:有些问题是,这是否适用于所有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());