记录器是否应该是私有静态的

2022-08-31 09:20:44

记录器是否应该声明为静态?通常我看到记录器的两种类型的声明:

    protected Log log = new Log4JLogger(aClass.class);

    private static Log log = new Log4JLogger(aClass.class);

应该使用哪一个?两者的利弊是什么?


答案 1

非静态形式的优点是,您可以在如下所示的(抽象)基类中声明它,而不必担心将使用正确的类名:

protected Log log = new Log4JLogger(getClass());

但是,它的缺点显然是将为类的每个实例创建一个全新的记录器实例。这本身可能并不昂贵,但它增加了显着的开销。如果您想避免这种情况,请改用表单。但它的缺点是,反过来,你必须在每个单独的类中声明它,并在每个类中注意在记录器的构造过程中使用了正确的类名,因为不能在静态上下文中使用。但是,在普通 IDE 中,您可以为此创建一个自动完成模板。例如: + .staticgetClass()loggerctrl+space

另一方面,如果您通过工厂获取记录器,而工厂又可以缓存已经实例化的记录器,那么使用非静态形式不会增加那么多开销。例如,Log4j有一个LogManager用于此目的。

protected Log log = LogManager.getLogger(getClass());

答案 2

我曾经认为所有的记录器都应该是静态的;但是,本文在 wiki.apache.org 提出了一些关于类装入器泄漏的重要内存问题。将记录器声明为静态可防止在使用共享类装入器的 J2EE 容器中对声明类(以及关联的类装入器)进行垃圾回收。如果重新部署应用程序足够多次,这将导致 PermGen 错误。

我真的没有看到任何方法来解决这个类加载器泄漏问题,除了将记录器声明为非静态。


推荐