Warum ist es in Java empfehlenswert, einen Logger zu deklarieren static final
?
private static final Logger S_LOGGER
private
- damit keine andere Klasse Ihren Logger entführen kannstatic
- Es gibt also nur eine Logger-Instanz pro Klasse, wodurch auch Versuche vermieden werden, Logger zu serialisierenfinal
- Der Logger muss während der gesamten Lebensdauer der Klasse nicht geändert werdenAußerdem bevorzuge ich, dass der Name log
so einfach wie möglich und dennoch beschreibend ist.
EDIT: Es gibt jedoch eine interessante Ausnahme zu diesen Regeln:
protected final Logger log = LoggerFactory.getLogger(getClass());
im Gegensatz zu:
private static final Logger log = LoggerFactory.getLogger(Foo.class);
Auf die erstere Weise können Sie in allen Klassen der Vererbungshierarchie denselben Loggernamen (Namen der tatsächlichen Klasse) verwenden. Wenn also Bar
verlängert Foo
, werden beide beim Bar
Logger protokolliert . Einige finden es intuitiver.
log
Namen angenehmer zu lesen, als den Code mit zu streuenLOG
. Nur eine Frage der Entwicklung. Teamvereinbarung.Überprüfen Sie diesen Blog-Beitrag: Befreien Sie sich von Java Static Loggers . So verwenden Sie slf4j mit jcabi-log :
Und verwenden Sie dieses statische Rauschen nie mehr.
quelle
static
bedeutet, dass Sie nur einen Logger pro Klasse erstellen, nicht einen Logger pro Instanz Ihrer Klasse. Im Allgemeinen ist dies das, was Sie möchten - da die Logger in der Regel nur je nach Klasse variieren.final
bedeutet, dass Sie den Wert derlogger
Variablen nicht ändern werden. Dies ist der Fall, da Sie fast immer alle Protokollnachrichten (von einer Klasse) an denselben Protokollierer senden. Selbst in den seltenen Fällen, in denen eine Klasse einige Nachrichten an einen anderen Logger senden möchte, ist es viel klarer, eine andere Logger-Variable (z. B.widgetDetailLogger
) zu erstellen, als den Wert einer statischen Variablen im laufenden Betrieb zu ändern.quelle
Wann möchten Sie den Wert des Feldes ändern?
Wenn Sie den Wert niemals ändern, wird durch das Festlegen des Felds deutlich, dass Sie den Wert niemals ändern werden.
quelle
Normalerweise initialisieren Sie den Logger so, dass er unter Verwendung des Klassennamens protokolliert wird. Wenn diese nicht statisch wären, würde jede Instanz der Klasse eine Instanz davon haben (hoher Speicherbedarf), aber alle diese Logger würden dies tun teilen die gleiche Konfiguration und verhalten sich genauso. Das ist der Grund für das
static
bisschen. DaLogger
Konflikte jeweils mit dem Klassennamen initialisiert werden, deklarieren Sieprivate
sie , um Konflikte mit Unterklassen zu vermeiden, damit sie nicht vererbt werden können. Dasfinal
kommt von dem Punkt, an dem Sie das normalerweiseLogger
während der Ausführung nicht ändern - also haben Sie es nach der Initialisierung nie "neu konfiguriert" - in diesem Fall ist es sinnvoll, es endgültig zu machen, um sicherzustellen, dass niemand es ändern kann (durch Fehler oder auf andere Weise). Natürlich, wenn Sie a verwenden wollenLogger
Auf eine andere Art und Weise müssen Sie möglicherweise NICHT verwendenstatic final
- aber ich wage zu vermuten, dass 80% der Apps die Protokollierung wie oben erläutert verwenden würden.quelle
Um diese Frage zu beantworten, sollten Sie sich gefragt haben, wofür "statisch" und "endgültig" sind.
Für einen Logger (ich nehme an, Sie sprechen über die Log4J Logger-Klasse) möchten Sie eine Kategorie pro Klasse. Dies sollte dazu führen, dass Sie es nur einmal zuweisen und nicht mehr als eine Instanz pro Klasse erforderlich ist. Und vermutlich gibt es keinen Grund, das Logger-Objekt einer Klasse einer anderen auszusetzen. Warum also nicht privat machen und einigen OO-Prinzipien folgen?
Beachten Sie auch, dass der Compiler davon profitieren kann. Ihr Code ist also etwas besser :)
quelle
Denn dies ist normalerweise die Art von Funktionalität, die für alle Instanzen Ihrer Objekte gemeinsam genutzt werden kann. Es ist nicht sehr sinnvoll (in 90% der Fälle), für zwei Instanzen derselben Klasse einen anderen Logger zu haben.
Manchmal sehen Sie jedoch auch Logger-Klassen, die als Singletons deklariert sind oder einfach statische Funktionen zum Protokollieren Ihrer Daten anbieten.
quelle
Dieser Code ist anfällig, aber nach Java7 können wir
Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
anstelle des statischen Loggers verwenden.quelle
This is code is vulnerable
Könnten Sie klarstellen, dass Sie ein bisschen antworten?In den meisten Fällen werden Sie die Referenz nicht ändern, und der
final
Modifikator markiert sie. Sie benötigen nicht für jede Klasseninstanz separate Instanzenstatic
. Und dies dient in erster Linie der Leistung - es kann gut optimiert werden (endgültig) und spart Speicher (statisch).quelle
Im Idealfall sollte Logger bis Java 7 wie folgt sein, um kein Sonar und einen kompatiblen Code anzugeben: privat: Niemals außerhalb der übergeordneten Klasse zugänglich sein. Wenn eine andere Klasse etwas protokollieren muss, sollte sie ihren eigenen Logger instanziieren. statisch: nicht abhängig von einer Instanz einer Klasse (einem Objekt). Wenn Sie etwas protokollieren, können natürlich Kontextinformationen in den Nachrichten bereitgestellt werden, aber der Logger sollte auf Klassenebene erstellt werden, um zu verhindern, dass zusammen mit jedem Objekt ein Logger erstellt wird und somit ein hoher Speicherbedarf vermieden wird. final: einmal und nur einmal pro Klasse erstellt werden.
quelle
Zusätzlich zu den in den anderen Antworten angegebenen Gründen stieß ich auf Folgendes, wenn mein Logger weder statisch noch endgültig war:
In bestimmten Fällen (wenn ich die Gson-Bibliothek verwendete) wurde eine Stackoverflow-Ausnahme angezeigt. Meine spezielle Situation bestand darin, die Klasse zu instanziieren, die den nicht statischen nicht endgültigen Logger enthält. Rufen Sie dann die toJson-Methode auf, die GsonBuilder aufgerufen hat:
quelle
Tatsächlich können statische Logger "schädlich" sein, da sie in einem statischen Kontext arbeiten sollen. In einer dynamischen Umgebung, z. OSGi kann es hilfreich sein, nicht statische Logger zu verwenden. Da einige Protokollierungsimplementierungen das interne Zwischenspeichern von Protokollierern durchführen (AFAIK mindestens log4j), können die Auswirkungen auf die Leistung vernachlässigbar sein.
Ein Nachteil von statischen Loggern ist z. Speicherbereinigung (wenn eine Klasse nur einmal verwendet wird, z. B. während der Initialisierung, bleibt der Logger weiterhin in der Nähe).
Weitere Details finden Sie unter:
Siehe auch:
quelle
Nach den Informationen, die ich aus dem Internet darüber gelesen habe, ob der Logger statisch ist oder nicht, ist es die beste Vorgehensweise, ihn entsprechend den Anwendungsfällen zu verwenden.
Es gibt zwei Hauptargumente:
1) Wenn Sie es statisch machen, wird kein Müll gesammelt (Speichernutzung und Leistung).
2) Wenn Sie es nicht statisch machen, wird es für jede Klasseninstanz erstellt (Speichernutzung)
Wenn Sie also einen Logger für einen Singleton erstellen, müssen Sie ihn nicht statisch machen. Weil es nur eine Instanz gibt, also einen Logger.
Wenn Sie dagegen einen Logger für ein Modell oder eine Entitätsklasse erstellen, sollten Sie es statisch machen, keine doppelten Logger zu erstellen.
quelle
Sie benötigen weiterhin einen statischen Logger für innere statische Klassen
quelle