LoggerFactory.getLogger(ClassName.class) vs LoggerFactory.getLogger(this.getClass().getName())

2022-09-01 11:48:14

我正在努力提高我在Java中的优化技能。为了实现这一目标,我有一个我制作的旧程序,我正在尽我所能让它变得更好。在这个程序中,我使用SL4J进行日志记录。为了获得记录器,我做了:

private static final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

在我编写代码时,我认为这是最好的选择,因为我删除了对类名的引用(可能会被重构)。但现在我不再那么肯定了...

private static final Logger logger = LoggerFactory.getLogger(ClassName.class);

另一方面,保留对类名的引用,但会删除一个方法调用。对于一个类来说,这可能不是一个很大的性能改进,但是当你有很多类时,这可能是一些东西。

所以我的问题是:

哪种方法更好?使用类名还是通过反射获取它?

请用利弊来激励你的答案。谢谢。


答案 1

晚到!

因为我将来可能会搜索这个。

有一种方法可以通过使用Java 7的MethodHandles类来创建复制/粘贴友好的Logger实例(考虑到这几乎从来都不是做某事的好理由!

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

答案 2

我会在这里分享我的意见。我想说的是,从性能的角度来看,您不应该被打扰。可能在代码中有一些部分可以比这个东西优化得更多:)

现在,关于你的问题。看看LoggerFactory的代码

请注意,只需调用重载方法:getLogger(Class<?> name)

Logger logger = getLogger(clazz.getName());

并进行一些额外的计算。因此,使用 String 的方法显然稍微快一些。

通常,该模式是将 Logger 引用维护为类中的静态字段,如下所示:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger(SomeClass.class);
}

在这种情况下,您无法真正使用,因为实际上并不存在(您在静态上下文中运行)。this.getClass()this

根据我的经验,最好将 它用作参数,除非你真的想使用来自不同类的同一记录器。在这种情况下,您最好使用一些表示记录器的逻辑常量。ClassName.getClass()

例如,假设您尝试使用 3 个不同的类来访问数据库。因此,您创建记录器“DB”,分配一个将写入数据库的文件追加器.log并且您希望在这3个不同的类中重用相同的记录器。

因此,您应该使用以下代码:

public class SomeClass {
   private static final Logger LOG =   LoggerFactory.getLogger("DB");
}

希望这有帮助


推荐