为什么日志要private static final

  private static final Log logger = LogFactory.getLog(SpringProperties.class);

对于使用PMD的任何人来说,如果日志记录器没有声明为静态的和final的,那么这个博客的标题就会出现在PMD错误列表中。具体地说,LoggerIsNotStaticFinal规则简单地说日志应该声明为静态的和final的。我也喜欢确保他们是私人的。例如:

//雅加达公共日志记录

private static final Log log = LogFactory.getLog(MyClass.class);

上面的代码还显示了另一个好的实践,即将Class对象传递给getLog()方法,而不是字符串。为什么java.util...Logger类甚至不提供接受Class对象的方法呢?为什么开发java.util.logging包的人将他们的API建立在Log4j上,却忽略了其中一些最有用的部分?哦,好吧。

现在说正题。为什么声明日志记录器是私有的、静态的和final的良好实践呢?日志记录器是一个内部实现细节,因此它应该是私有的。对于类的所有实例,您只需要一个日志记录器,因此是静态的。并且记录器不能被替换,因此是最终的。所以如果这是好的,有什么不好的(至少在我看来)?Simple——任何不是私有的、静态的、final的记录器,并且不会将Class对象传递给getLog()!例如,考虑这个公共代码位,它在某个基类中声明:

//记录器声明不太好

protected final Log log = LogFactory.getLog(getClass());

为什么这么糟糕?嗯,它不是静态的。另一方面,它使用getClass()来获取日志。起初,这似乎很有效,因为现在所有子类都自动继承了正确运行时类型的现成的日志。这里出了什么问题?以这种方式声明的日志记录器的最大问题是,您现在从超类中获得的所有日志记录与子类的日志记录混合在一起,并且在日志输出中,除非您查看源代码,否则无法识别哪些消息来自哪个类。如果超类有很多您不想看到的日志记录,这是非常烦人的,因为您不能过滤掉它。

另一个问题是,您以不同的方式设置日志级别的能力消失了,例如,如果子类驻留在与超类不同的包中。在这种情况下,如果试图从超类中筛选出日志记录,则不能,因为实际的运行时类用于获取日志记录器。

最后,拥有一个受保护的记录器似乎违反了基本的面向对象原则。为什么子类应该从横切关注点的超类了解内部实现细节?无论如何,虽然这是一个愚蠢的小咆哮,但是当您扩展一个声明像这样的受保护日志记录器的超类时,它确实很烦人。

猜你喜欢

转载自my.oschina.net/u/3005325/blog/2988417