log4j.Logger中getLogger的通用方式

而不是在每个类上指定类名:

log = Logger.getLogger(Foo.class); log = Logger.getLogger(Bar.class); log = Logger.getLogger(Test.class); 

可以使用:

 log = Logger.getLogger(this.getClass()); 

会有什么影响?

如果创建子类,日志消息将记录到子类的记录器中。

 package pkgone; public class SuperType { private Logger log = Logger.getLogger(this.getClass()); public void someAction() { log.info("Doing something"); } } 

 package pkgtwo; import pkgone.SuperType; public class SubType extends SuperType { // for instances of SubType, the log object in SuperType // will get initialized with SubType's class object } 

 // some code somewhere that uses SubType SubType obj = new SubType(); obj.someAction(); 

在上面的示例中,“执行某些操作”将记录到pkgtwo.SubType记录器而不是pkgone.SuperType记录器,这可能是您想要的,也可能不是。

尝试这种方式查找generics类…

 private static final Log LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass()); 

最好的部分是静态使用此方法。

如果您不想重复编写logger并希望避免写错错的类名,那么Project Lombok就是@Log 。

如果您不介意在项目中再使用一个库,则只需添加一个带有简单注释的记录器即可。

 import lombok.extern.java.Log; import lombok.extern.slf4j.Slf4j; @Log public class LogExample { public static void main(String... args) { log.error("Something's wrong here"); } } 

当然看起来很好。

请注意,一个含义是,如果您可能无法从静态上下文中使用日志 – 它可能未初始化或可能不可见

对于调用超级方法的子类实例+1,记录器将是子类。

此外,如果您将此作为类的日志记录模板应用,如果您的类是抽象的 – 您的this.getClass将失败,因为您没有此类的实例。

使用Apache commons的日志工厂:

 import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.log4j.Logger; public class SomeNewClass { ... private final Log logger = LogFactory.getLog(this.getClass()); ... } 

不必做任何其他事情。 不确定LogFactory在问题发布时是否可用。 如果你不想使用LogFactory,你也可以简单地使用带有getClass()的private final。

 private final Logger log = Logger.getLogger(this.getClass()); 

没有理由创建子类,除非您想要记录日志记录,这也可以通过操作日志配置文件来完成(log4j.xml,如果你正在使用它)。 当记录器定义为静态时,您无法使用this.getClass()。 如果没有静态或私有的最终结果,您可以让记录器对您不想要的危险的可能更改保持开放状态。

据我所知,没有任何影响。 根据马特评论,我猜,这是每个人都想要的正确行为。