logging器应该是私有的静态或不
logging器是否应声明为静态? 通常我已经看到了两种types的logging器声明:
保护日志日志=新Log4JLogger(aClass.class);
要么
private static Log log = new Log4JLogger(aClass.class);
哪一个应该使用? 什么是两者的亲和骗局?
非静态表单的好处是你可以像下面那样在(抽象)基类中声明它,而不用担心会使用正确的类名:
protected Log log = new Log4JLogger(getClass());
然而,它的缺点显然是将为每个类的实例创build一个全新的logging器实例。 这本身可能并不昂贵,但是会增加很大的开销。 如果你想避免这种情况,你想使用static
forms。 但是它的缺点是你必须在每个单独的类中声明它,并在每个类中注意在logging器的构造过程中使用了正确的类名,因为getClass()
不能在静态上下文中使用。 但是,在平均IDE中,您可以为此创build一个自动完成模板。 例如logger
+ ctrl+space
。
另一方面,如果您通过工厂获取logging器,而工厂又可以caching已经实例化的logging器,那么使用非静态表单将不会增加那么多的开销。 例如Log4j有一个LogManager
用于这个目的。
protected Log log = LogManager.getLogger(getClass());
我曾经认为,所有伐木者应该是静态的; 然而, 这篇文章在wiki.apache.org上提到了一些关于类加载器泄漏的重要的内存问题。 将logging器声明为静态可防止声明类(和关联的类加载器)在使用共享类加载器的J2EE容器中被垃圾收集。 这会导致PermGen错误,如果您重新部署您的应用程序足够多的时间。
我真的没有办法解决这个类加载器泄漏问题,除了声明logging器是非静态的。
最重要的区别是它如何影响你的日志文件:日志去哪个类别?
- 在你的第一个select中,子类的日志以超类的类别结束。 这对我来说似乎是非常直观的。
-
你的第一个案例有一个变种:
保护日志日志=新Log4JLogger(getClass());
在这种情况下,您的日志类别将logging正在处理的代码的哪个对象。
-
在第二种select(私有静态)中,日志类别是包含日志代码的类。 所以正常情况下,正在做logging的东西的类。
我强烈build议最后的select。 与其他解决scheme相比,它具有以下优点:
- 日志和代码之间有直接的关系。 很容易find日志消息来自哪里。
- 如果有人需要调整日志级别(这是每个类别完成的),通常是因为他们对特定的消息感兴趣(或不是),特定的消息由特定的类编写。 如果类别不是正在编写消息的类,则难以调整级别。
- 您可以login静态方法
- logging器只需要每个类初始化(或查找)一次,所以在启动时,而不是每个创build的实例。
它也有缺点:
- 它需要在你logging消息的每个类中声明(不要重用超类logging器)。
- 在初始化logging器时,需要注意input正确的类名。 (但好的IDE为你照顾)。
使用控制反转并将logging器传递给构造函数。 如果你在课堂上创buildlogging器,那么你的unit testing将会有一段时间。 你正在写unit testing不是吗?