10

我的 Java 生锈了,所以请多多包涵。在 CI 中可以做到:

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 编译器在处理源代码时真的不知道它在中间的类吗?

4

3 回答 3

8

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

对于这种特殊情况,另一种方法是使用log5j。log5j 是 log4j 的一个包装器,带有类似的便捷方法getLogger(),它通过在堆栈中向上走来推断正确的类。所以你的代码会变成:

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

您可以毫无问题地将相同的声明复制并粘贴到您的所有类中。

于 2009-07-02T18:37:30.100 回答
7

我抗拒不了。

这是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());
    }

}
于 2009-07-02T19:11:56.320 回答
4
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
return trace[2].getClassName();

恕我直言,获取堆栈跟踪的更简洁方法

于 2010-12-09T11:55:56.933 回答