¿Por qué declaramos que los registradores son estáticos?

En Java, ¿por qué es una buena práctica declarar un registrador static final ?

 private static final Logger S_LOGGER 

  • private – para que ninguna otra clase pueda secuestrar su registrador
  • static , por lo que solo hay una instancia de registrador por clase, lo que también evita los bashs de serializar registradores
  • final : no es necesario cambiar el registrador durante la vida útil de la clase

Además, prefiero que el log nombre sea lo más simple posible, pero descriptivo.

EDITAR: Sin embargo, hay una excepción interesante a estas reglas:

 protected final Logger log = LoggerFactory.getLogger(getClass()); 

Opuesto a:

 private static final Logger log = LoggerFactory.getLogger(Foo.class); 

La forma anterior le permite usar el mismo nombre de registrador (nombre de la clase real) en todas las clases en toda la jerarquía de herencia. Entonces, si Bar extiende Foo , ambos se registrarán en Bar logger. Algunos lo encuentran más intuitivo.

Verifique esta publicación en el blog: Deshágase de los registradores estáticos de Java . Así es como usas slf4j con jcabi-log :

 import com.jcabi.log.Logger; class Foo { void save(File f) { Logger.info(this, "file %s saved successfully", f); } } 

Y nunca más uses ese ruido estático.

static significa que solo crea un Logger por clase, no un registrador por instancia de su clase. En general, esto es lo que quiere, ya que los madereros tienden a variar únicamente en función de la clase.

final significa que no va a cambiar el valor de la variable del logger . Lo cual es cierto, ya que casi siempre arrojas todos los mensajes de registro (de una clase) al mismo registrador. Incluso en las raras ocasiones en que una clase podría querer enviar algunos mensajes a un registrador diferente, sería mucho más claro crear otra variable de registrador (por ejemplo, widgetDetailLogger ) en lugar de mutar el valor de una variable estática sobre la marcha.

¿Cuándo quieres cambiar el valor del campo?

Si nunca va a cambiar el valor, hacer el campo final hace que sea obvio que nunca cambiará el valor.

Para responder a esa pregunta, deberías haberte preguntado para qué son “estáticos” y “finales”.

Para un Logger, (supongo que hablas de la clase Log4J Logger) quieres una categoría por clase. Lo cual debería llevar al hecho de que lo asigne solo una vez, y no hay necesidad de más de una instancia por clase. Y, presumiblemente, no hay ninguna razón para exponer el objeto Logger de una clase a otra, entonces, ¿por qué no hacerlo privado y seguir algunos OO-Principles?

También debe tener en cuenta que el comstackdor puede aprovechar los beneficios de eso. Entonces tu código funciona un poco mejor 🙂

Porque ese suele ser el tipo de funcionalidad que se puede compartir en todas las instancias de sus objetos. No tiene mucho sentido (90% del tiempo) tener un registrador diferente para dos instancias de la misma clase.

Sin embargo, también puede ver a veces las clases de registrador declaradas como singleton o simplemente ofreciendo funciones estáticas para registrar sus cosas.

Normalmente se inicializa el registrador para que se registre usando el nombre de la clase, lo que significa que si no fueran estáticos, terminaría teniendo cada instancia de la clase con una instancia (huella de memoria alta), pero todos estos registradores comparte la misma configuración y se comporta exactamente igual. Esa es la razón detrás del bit static . Además, dado que cada Logger se inicializa con el nombre de la clase, para evitar conflictos con las subclases, se declara private por lo que no se puede heredar. La final viene del punto de que normalmente no cambia el Logger durante la ejecución, por lo que una vez inicializado nunca lo “reconfigurará”, en cuyo caso tiene sentido hacerlo definitivo para garantizar que nadie pueda cambiarlo. (por error o de otro modo). Por supuesto, si vas a utilizar un Logger de una manera diferente, es posible que NO necesites utilizar static final , pero me atrevo a adivinar que el 80% de las aplicaciones usaría el registro como se explicó anteriormente.

Este código es vulnerable, pero, después de Java7, podemos usar Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); en lugar de registrador estático

En la mayoría de los casos, no va a cambiar la referencia y el modificador final marca. No necesita instancias separadas para cada instancia de clase, por lo que static . Y, en primer lugar, esto es para el rendimiento : se puede optimizar muy bien (final) y ahorra memoria (estática).

Además de las razones dadas en las otras respuestas, una cosa con la que me encontré fue que mi registrador no era estático ni definitivo:

 ... public Logger logger = LoggerFactory.getLogger(DataSummary.class); public String toJson() { GsonBuilder gsonBuilder = new GsonBuilder(); return gsonBuilder.create().toJsonTree(this).toString(); } ... 

en ciertos casos (cuando estaba usando la biblioteca Gson) obtendría la excepción de stackoverflow. Mi situación específica era instanciar la clase que contiene el registrador no final no estático. Luego llame al método toJson que invoca GsonBuilder:

 ... DataSummary ds = new DataSummary(data); System.out.println(ds.toJson()); ... 

Aún necesita un registrador estático para clases internas estáticas