java - titledborder - En caso de que el registrador sea privado estático o no
titledborder java (4)
¿Debería el registrador declararse estático o no? Por lo general, he visto dos tipos de declaraciones para un registrador:
protected Log log = new Log4JLogger(aClass.class);
o
private static Log log = new Log4JLogger(aClass.class);
¿Cuál debería ser usado? ¿Cuales son las ventajas y desventajas de ambos?
La diferencia más importante es cómo afecta sus archivos de registro: ¿en qué categoría van los registros?
- En su primera elección, los registros de una subclase terminan en la categoría de la superclase. Eso me parece muy contrario a la intuición.
Hay una variante de tu primer caso:
registro de registro protegido = nuevo Log4JLogger (getClass ());
En ese caso, su categoría de registro indica en qué objeto estaba trabajando el código que inició sesión.
En su segunda opción (privada estática), la categoría de registro es la clase que contiene el código de registro. Entonces, normalmente, la clase que está haciendo lo que se está registrando.
Recomiendo encarecidamente esa última opción. Tiene estas ventajas, en comparación con las otras soluciones:
- Hay una relación directa entre el registro y el código. Es fácil encontrar el origen de un mensaje de registro.
- Si alguien tiene que ajustar los niveles de registro (lo cual se hace por categoría), generalmente se debe a que están interesados (o no) en algunos mensajes en particular, escritos por una clase en particular. Si la categoría no es la clase que está escribiendo los mensajes, es más difícil sintonizar los niveles.
- Puede iniciar sesión en métodos estáticos
- Los madereros solo necesitan inicializarse (o buscar) una vez por clase, por lo que al inicio, en lugar de por cada instancia creada.
También tiene desventajas:
- Debe declararse en todas las clases donde se registran los mensajes (sin reutilización de los registradores de superclase).
- Debe tener cuidado de poner el nombre de clase correcto al inicializar el registrador. (Pero los buenos IDE se encargan de eso).
La ventaja de la forma no estática es que puedes declararla en una clase base (abstracta) de la siguiente manera sin preocuparte de que se use el nombre de clase correcto:
protected Log log = new Log4JLogger(getClass());
Sin embargo, su desventaja es obviamente que se creará una nueva instancia de registrador para cada instancia de la clase. Esto puede no ser costoso en sí mismo, pero agrega una sobrecarga significativa. Si desea evitar esto, le gustaría usar la forma static
lugar. Pero su desventaja es, a su vez, que debe declararlo en cada clase individual y tener cuidado en cada clase de que se use el nombre de clase correcto durante la construcción del registrador porque getClass()
no se puede usar en contexto estático. Sin embargo, en el IDE promedio puede crear una plantilla de autocompletar para esto. Eg logger
+ ctrl+space
.
Por otro lado, si obtiene el registrador por una fábrica que a su vez puede almacenar en caché los registradores ya instanciados, entonces usar la forma no estática no agregará esa sobrecarga. Log4j, por ejemplo, tiene un LogManager
para este propósito.
protected Log log = LogManager.getLogger(getClass());
Solía pensar que todos los registradores deberían ser estáticos; sin embargo, este artículo en wiki.apache.org trae algunas preocupaciones importantes sobre la memoria, con respecto a las filtraciones del cargador de clases. Declarar un registrador como estático evita que la clase declarante (y los cargadores de clase asociados) sean basura recogida en contenedores J2EE que usan un cargador de clases compartido. Esto generará errores de PermGen si vuelve a implementar su aplicación las veces necesarias.
Realmente no veo ninguna forma de evitar este problema de fuga del cargador de clases, aparte de declarar que los registradores no son estáticos.
Use la inversión del control y pase el registrador al constructor. Si crea el registrador dentro de la clase, tendrá un diablo con las pruebas de su unidad. Usted está escribiendo pruebas unitarias, ¿no?