为什么日志器(logger)要声明为static final的?

我用PMD的代码分析工具来分析一个项目源代码,提示logger 没有被声明为static final的,很疑惑~

找到一篇blog如是说:
原文链接
http://www.nofluffjuststuff.com/blog/scott_leberknight/2007/03/loggerisnotstaticfinal.html

For anyone who uses PMD, the title of this blog appears in their list of PMD errors if they don't declare their loggers static and final. Specifically, the LoggerIsNotStaticFinal rule simply says that a log should be declared static and final. I also like to make sure they are private as well. For example:

// Jakarta Commons Logging
private static final Log log = LogFactory.getLog(MyClass.class);
The above code also shows another good practice, which is to pass the Class object to the getLog() method, instead of a string. Why the java.util.logging.Logger class doesn't even provide a method accepting a Class object is simply beyond me. Why did the people who developed the java.util.logging package base their API on Log4j yet omit some of the most useful parts of it? Oh well.

Now to the point. Why it is good practice to declare loggers private, static, and final? A logger is an internal implementation detail, so it should be private. You only need one logger for all instances of a class, hence static. And a logger should not be able to be replaced, thus final. So if this is good, what's not so good (at least in my opinion)? Simple - any logger that is not private, static, final, and which doesn't pass in a Class object to getLog()! For example, consider this common bit of code, declared in some base class:

// Not so good logger declaration
protected final Log log = LogFactory.getLog(getClass());
Why is this bad? Well, it isn't static for one thing. For another, it uses getClass() to obtain the log. At first this seems efficient since now all subclasses automatically inherit a ready-made log of the correct runtime type. So what's the issue here? The biggest problem with loggers declared in this manner is that you now get all the logging from the superclass mixed in with the logging from the subclass, and it is impossible in the log output to discern which messages came from which class unless you look at the source. This is really annoying if the superclass has a lot of logging that you don't want to see, since you cannot filter it out.

Another problem is that your ability to set log levels differently goes away, for example if a subclass resides in a different package than the superclass. In that case, if you try to filter out logging from the superclass, you can't because the actual runtime class was used to obtain the logger.

Last, having a protected logger just seems to violate basic object-oriented principles. Why in the world should subclasses know about an internal implementation detail from a superclass that is a cross-cutting concern, no less? Anyway, though this is a silly little rant it really is annoying when you extend a superclass that declares a protected logger like this.

使用AOP是一个方向,但是性能问题是个麻烦。<BR><BR>使用Anonation可能是一个方向

(1):出于资源利用的考虑,LOGGER的构造方法参数是Class,决定了LOGGER是根据
类的结构来进行区分日志,所以一个类只要一个LOGGER就可以了,故static
(2):final表示一种编程习惯,表示该类的LOGGER只是记录该类的信息,否则日志
会无法提供可以令人信服的记录