Aur*_*ere 14 java reflection optimization logging slf4j
我正在努力提高我的Java优化技能.为了实现这一目标,我制作了一个旧程序,并且我正在尽力使其变得更好.在这个程序中,我使用SL4J进行日志记录.为了得到我做的记录器:
private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
Run Code Online (Sandbox Code Playgroud)
在我编写代码的时候,我认为这是最好的选择,因为我删除了对类名的引用(可能会被重构).但现在我不再那么肯定了......
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
Run Code Online (Sandbox Code Playgroud)
另一方面,保留对类名的引用,但它会删除一个方法调用.对于一个班级来说,这可能不是一个很大的改进,但是当你有很多班级时,这可能就是一个问题.
所以我的问题是:
哪种方法更好?使用类名还是通过反射获取?
请用正反面来激励你的答案.谢谢.
Mar*_*ren 12
迟到!
因为我将来可能会寻找这个。
有一种方法可以通过使用 Java 7 的 MethodHandles 类来创建对复制/粘贴友好的 Logger 实例(当然这几乎从来都不是做某事的好理由!)。
private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Run Code Online (Sandbox Code Playgroud)
Mar*_*nik 10
我会在这里分享我的意见.我会说这是你不应该从性能的角度来打扰的情况.可能在代码中有部分可以比这个东西更优化:)
现在,关于你的问题.看看LoggerFactory的代码
请注意,getLogger(Class<?> name)只需调用重载方法:
Logger logger = getLogger(clazz.getName());
Run Code Online (Sandbox Code Playgroud)
并进行一些额外的计算.所以使用String的方法显然要快一些.
通常,模式是将Logger引用保持为类中的静态字段,如下所示:
public class SomeClass {
private static final Logger LOG = LoggerFactory.getLogger(SomeClass.class);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您无法真正使用,this.getClass()因为this实际上并不存在(您在静态上下文中运行).
根据我的经验,ClassName.getClass()除非您真的想要使用来自不同类的相同记录器,否则最好将其用作参数.在这种情况下,您最好使用一些表示记录器的逻辑常量.
例如,假设您尝试使用3个不同的类来访问数据库.因此,您创建记录器"DB",分配将写入database.log的文件追加器,并且您希望在这3个不同的类中重用相同的记录器.
所以你应该使用以下代码:
public class SomeClass {
private static final Logger LOG = LoggerFactory.getLogger("DB");
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助
我通常做的是
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
Run Code Online (Sandbox Code Playgroud)
但是,这个成语
protected final Logger log = LoggerFactory.getLogger(getClass());
Run Code Online (Sandbox Code Playgroud)
同样很常见.在这个问题中,您可以找到有关这些约定的更多信息.
小智 5
我更喜欢
Logger logger = LoggerFactory.getLogger(ClassName.class);
Run Code Online (Sandbox Code Playgroud)
因为
this.getClass()
Run Code Online (Sandbox Code Playgroud)
可以由一个类子项覆盖,您将在日志中看到子类名.有时它可能会令人困惑,因为日志实际上是在父类中执行的