为了在类中初始化 Log4j,程序员需要提供实例Class(或表示它的字符串名称)。代码如下所示:
public class MyClass {
private static Log logger = Logger.getLogger(MyClass.class);
[...]
}
Run Code Online (Sandbox Code Playgroud)
然后 Log4j 将根据程序员给出的参数提供输出。输出将如下所示:
[INFO] [MyClass:124] Foobar
Run Code Online (Sandbox Code Playgroud)
我的问题:如果 Log4j 知道日志记录语句的行号是什么( 124),那么为什么它需要类名(MyClass)?在我看来,如果能弄清楚前者,就应该能够弄清楚后者。
编辑:这也不是一个闲置的问题;我们大多数人都见过这样的代码:程序员不小心从另一个类中复制并粘贴了初始化代码,但忘记更改初始化程序中的类名。这会导致 Log4j 提供令人困惑的输出。
(当然,我的问题并没有说明具体问题,但它对我理解 Log4j 和可能的 Java 反射如何工作很有帮助)。
小智 1
要解决“复制和粘贴”问题,请尝试在代码中使用 getClass() 方法,这样当您将记录器声明复制并粘贴到新类时,它会使用自己的类名,如下所示:
private Logger log = Logger.getLogger(this.getClass());
Run Code Online (Sandbox Code Playgroud)
Log4j 实际上会在类名上调用 .getName(),因此它有一个用于记录器的字符串名称。事实上,您可以在其中放置任何字符串,但约定是使用类名。
还可能存在这样的用例,您希望在类 B 中使用类 A 的记录器。也许 B 是内部类的子类或一部分,并且您希望日志输出看起来像是来自相同的日志名称(类名称) 。前任:
public class MyClassB extends MyClassA {
private static Log logger = Logger.getLogger(MyClassB.class);
[...]
}
Run Code Online (Sandbox Code Playgroud)