En Java, pourquoi est-il recommandé de déclarer un enregistreur static final
?
private static final Logger S_LOGGER
private
- pour qu'aucune autre classe ne puisse détourner votre enregistreurstatic
- il n'y a donc qu'une seule instance d'enregistreur par classe, évitant également les tentatives de sérialisation des enregistreursfinal
- pas besoin de changer l'enregistreur pendant la durée de vie de la classeDe plus, je préfère que le nom log
soit aussi simple que possible, mais descriptif.
EDIT: Cependant, il existe une exception intéressante à ces règles:
protected final Logger log = LoggerFactory.getLogger(getClass());
par opposition à:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
La première méthode vous permet d'utiliser le même nom d'enregistreur (nom de la classe réelle) dans toutes les classes de la hiérarchie d'héritage. Donc, si Bar
s'étend Foo
, les deux se connecteront à l' Bar
enregistreur. Certains le trouvent plus intuitif.
log
plutôt que de disperser le code avecLOG
. Juste une question de développement. accord d'équipe.Consultez ce billet de blog: Débarrassez-vous des enregistreurs statiques Java . Voici comment vous utilisez slf4j avec jcabi-log :
Et n'utilisez plus jamais ce bruit statique.
la source
static
signifie que vous ne créez qu'un seul enregistreur par classe, pas un enregistreur par instance de votre classe. En général, c'est ce que vous voulez - car les enregistreurs ont tendance à varier uniquement en fonction de la classe.final
signifie que vous n'allez pas changer la valeur de lalogger
variable. Ce qui est vrai, puisque vous lancez presque toujours tous les messages de journal (d'une classe) au même enregistreur. Même dans les rares occasions où une classe pourrait vouloir envoyer des messages à un autre enregistreur, il serait beaucoup plus clair de créer une autre variable de journalisation (par exemplewidgetDetailLogger
) plutôt que de muter la valeur d'une variable statique à la volée.la source
Quand voudriez-vous changer la valeur du champ?
Si vous ne modifiez jamais la valeur, le fait de rendre le champ définitif indique clairement que vous ne changerez jamais la valeur.
la source
Normalement, vous initialisez l'enregistreur pour qu'il enregistre en utilisant le nom de la classe - ce qui signifie que s'ils n'étaient pas statiques, vous vous retrouveriez avec chaque instance de la classe en ayant une instance (empreinte mémoire élevée), mais tous ces enregistreurs partagent la même configuration et se comportent exactement de la même manière. C'est la raison derrière le
static
bit. De plus, parce que chacunLogger
est initialisé avec le nom de la classe, pour éviter les conflits avec les sous-classes, vous le déclarezprivate
afin qu'il ne puisse pas être hérité. Lefinal
vient du point que vous normalement ne modifiez pas leLogger
cours de l'exécution - une fois que vous initialisés jamais « reconfiguré » - dans ce cas , il est logique de le rendre définitif pour assurer que personne ne peut changer (par erreur ou autre). Bien sûr, si vous allez utiliser unLogger
d'une manière différente, vous n'aurez peut-être PAS besoin de l'utiliserstatic final
- mais je me risquerais à penser que 80% des applications utiliseraient la journalisation comme expliqué ci-dessus.la source
Pour répondre à cette question, vous auriez dû vous demander à quoi servent les termes «statique» et «final».
Pour un enregistreur, (je suppose que vous parlez de la classe Log4J Logger), vous voulez une catégorie par classe. Ce qui devrait conduire au fait que vous ne l'attribuez qu'une seule fois et qu'il n'y a pas besoin de plus d'une instance par classe. Et il n'y a probablement aucune raison d'exposer l'objet Logger d'une classe à une autre, alors pourquoi ne pas le rendre privé et suivre quelques principes OO.
Notez également que le compilateur est capable d'en tirer profit. Donc, votre code fonctionne un peu mieux :)
la source
Parce que c'est généralement le type de fonctionnalité qui peut être partagée entre toutes les instances de vos objets. Cela n'a pas beaucoup de sens (90% du temps) d'avoir un enregistreur différent pour deux instances de la même classe.
Cependant, vous pouvez également voir parfois des classes de journalisation déclarées comme des singletons ou même simplement proposer des fonctions statiques pour enregistrer vos données.
la source
Ce code est vulnérable , mais, après Java7, nous pouvons utiliser à la
Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
place d'un enregistreur statique.la source
This is code is vulnerable
Pourriez-vous clarifier votre réponse un peu?Dans la plupart des cas, vous n'allez pas modifier la référence et le
final
modificateur la marque. Vous n'avez pas besoin d'instances distinctes pour chaque instance de classe - doncstatic
. Et tout d'abord, c'est pour la performance - il peut être bien optimisé (final) et économise de la mémoire (statique).la source
Idéalement, Logger devrait être comme suit jusqu'à Java 7, pour ne pas donner de Sonar et donner un code conforme: private: ne jamais être accessible en dehors de sa classe parente. Si une autre classe a besoin de consigner quelque chose, elle doit instancier son propre enregistreur. statique: ne pas être dépendant d'une instance d'une classe (un objet). Lors de la journalisation de quelque chose, des informations contextuelles peuvent bien sûr être fournies dans les messages, mais l'enregistreur doit être créé au niveau de la classe pour éviter de créer un enregistreur avec chaque objet et ainsi empêcher l'empreinte mémoire élevée. final: être créé une et une seule fois par classe.
la source
En plus des raisons données dans les autres réponses, une chose que j'ai rencontrée était que si mon enregistreur n'était ni statique ni définitif:
dans certains cas (lorsque j'utilisais la bibliothèque Gson), j'obtiendrais une exception stackoverflow. Ma situation spécifique était d'instancier la classe contenant le logger non statique non final. Appelez ensuite la méthode toJson qui a appelé GsonBuilder:
la source
En fait, les enregistreurs statiques peuvent être «nuisibles» car ils sont censés fonctionner dans un contexte statique. Lorsque vous avez un environnement dynamique, par exemple. OSGi, il peut être utile d'utiliser des enregistreurs non statiques. Comme certaines implémentations de journalisation font une mise en cache des enregistreurs en interne (AFAIK au moins log4j), l'impact sur les performances peut être négligeable.
Un inconvénient des enregistreurs statiques est par exemple. garbage collection (lorsqu'une classe n'est utilisée qu'une seule fois, par exemple lors de l'initialisation, l'enregistreur sera toujours conservé).
Pour plus de détails, consultez:
Voir également:
la source
Selon les informations que j'ai lues sur Internet pour rendre l'enregistreur statique ou non, la meilleure pratique consiste à l'utiliser en fonction des cas d'utilisation.
Il y a deux arguments principaux:
1) Lorsque vous le rendez statique, il n'est pas ramassé (utilisation de la mémoire et performances).
2) Lorsque vous ne le rendez pas statique, il est créé pour chaque instance de classe (utilisation de la mémoire)
Ainsi, lorsque vous créez un enregistreur pour un singleton, vous n'avez pas besoin de le rendre statique. Parce qu'il n'y aura qu'une seule instance donc un enregistreur.
D'autre part, si vous créez un enregistreur pour un modèle ou une classe d'entité, vous devez le rendre statique pour ne pas créer d'enregistreurs dupliqués.
la source
Vous avez toujours besoin d'un enregistreur statique pour les classes statiques internes
la source