在Java静态方法声明中使用当前类

时间:2009-07-02 18:23:40

标签: java class introspection

我的Java生锈了所以请耐心等待。在C中我可以做到:

int someFunc(void)
{
  printf("I'm in %s\n", __func__);
}

在Java中,我可以通过词汇方式获取当前正在定义的类型的名称或类。例如,如果我有:

import org.apache.log4j.Logger;

class myClass {
    private static final Logger logger = Logger.getLogger(myClass.class);
...
}

在getLogger()参数中重复“myClass”似乎是错误的。我想要“getLogger(__ CLASS__)”或“getLogger(this.class)”之类的东西。 (我知道这些都是愚蠢的,但它们应该指向我正在寻找的东西。)Java编译器在处理源代码时是否真的不知道它在哪个类中?

3 个答案:

答案 0 :(得分:9)

不幸的是,如果您处于static上下文(就像您在这里),没有更简单的方法。如果记录器是一个实例变量,你可以使用getClass(),但是你必须担心子类。

对于这种特殊情况,另一种方法是使用log5j代替。 log5j是log4j的包装器,带有方便的方法,如getLogger(),它通过向上走栈来推断出正确的类。所以你的代码将成为:

import com.spinn3r.log5j.Logger;
class myClass {
    private static final Logger logger = Logger.getLogger();
    ...
}

您可以将相同的声明复制并粘贴到所有类中,而不会出现任何问题。

答案 1 :(得分:6)

我无法抗拒。

这是mmyers所指的但是自制的实现:)

基本上你抛出一个异常并获取堆栈的第二个元素来获取类名。

我仍然认为将它作为实例成员更好。

:)

package some.utility.packagename;   
import java.util.logging.Logger;

import some.other.packagename.MyClass;

public class LoggerFactory {
    public static Logger getLogger() {
        StackTraceElement [] s = new RuntimeException().getStackTrace();
        return Logger.getLogger( s[1].getClassName() );
    }
    public static void main (String [] args) {
        MyClass a = new MyClass();
    }
}

用法:

package some.other.packagename;
import java.util.logging.Logger;

import static some.utility.packagename.LoggerFactory.getLogger;

public class MyClass {

    private static final Logger logger = getLogger();
    static{
         System.out.println(MyClass.logger.getName());
    }

}

答案 2 :(得分:4)

StackTraceElement[] trace = Thread.currentThread().getStackTrace();
return trace[2].getClassName();

恕我直言更简洁的方式获得堆栈跟踪