Verwendung von java.util.logging

Grundlegende Verwendung

Zunächst die Grundnutzung. Die Hauptauftritte sind die folgenden drei.

  1. Logger - Ein Objekt, das Protokolle ausgibt.
  2. Handler - Ein Objekt, das das Ausgabeziel des Protokolls steuert.
  3. Formatierer - Ein Objekt, das das Format des Protokolls steuert.

Erstellen Sie zunächst eine Logger-Instanz.

Logger logger = Logger.getLogger("Loggername")

Erstellen Sie als Nächstes eine Handler-Instanz und registrieren Sie sie beim Logger. Sie können mehrere Handler registrieren. Erstellen Sie dieses Mal einen Handler mit "C: \ sample \ sample.log" als Ausgabeziel. Wenn Sie in eine Datei ausgeben möchten, verwenden Sie die 'Handler'-Schnittstellenimplementierungsklasse' FileHandler '.

Handler handler = new FileHandler("C:\\sample\\sample.log");
logger.addHandler(handler);

Erstellen Sie abschließend eine Formatter-Instanz und registrieren Sie sie im Handler. Dieses Mal werden wir "SimpleFormatter" verwenden, um es in einer Form zu formatieren, die für Menschen leicht zu lesen ist. SimpleFormatter ist eine Implementierungsklasse der Formatter-Schnittstelle.

Formatter formatter =  new SimpleFormatter();
handler.setFormatter(formatter);

Jetzt können Sie loslegen. Übergeben Sie die Nachricht an den Logger und geben Sie das Protokoll aus.

logger.log(Level.INFO, "Botschaft");

Wie oben erwähnt, geben Sie bei der Ausgabe des Protokolls die Protokollstufe der Nachricht an. Die folgenden 7 Arten von Protokollebenen werden von java.util.logging vorbereitet. Je tiefer Sie gehen, desto ernster wird das Protokoll.

--FINE ST-- Sehr detaillierte Trace-Nachricht --FINER - Eine ziemlich detaillierte Trace-Nachricht --FINE - Detaillierte Trace-Nachricht --CONFIG --Statische Konfigurationsmeldung --INFO --Informationsnachricht --WARNUNG --Warnung --SEVERE --Kritische Nachricht

Sie können den Logger so einstellen, dass nur Nachrichten über einer bestimmten Protokollstufe ausgegeben werden. Wenn Sie beispielsweise nur Nachrichten mit INFO-Level oder höher ausgeben möchten, stellen Sie Folgendes ein.

logger.setLevel(Level.INFO);

Das Beispielprogramm für die grundlegende Verwendung wird unten beschrieben.

BasicLoggingSample


package sample;

import java.io.IOException;
import java.util.function.Supplier;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class BasicLoggingSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Holen Sie sich den Logger und setzen Sie die Log-Ebene auf INFO
		Logger logger = Logger.getLogger(BasicLoggingSample.class.getName());
		logger.setLevel(Level.INFO);

		//Erstellen Sie einen Handler und registrieren Sie ihn als Logger
		Handler handler = new FileHandler("C:\\sample\\sample.log");
		logger.addHandler(handler);
		
		//Erstellen Sie einen Formatierer und registrieren Sie ihn als Handler
		Formatter formatter =  new SimpleFormatter();
		handler.setFormatter(formatter);
		
		//INFO-Nachricht ausgeben
		logger.log(Level.INFO, "INFO Nachricht");

		//Es gibt eine einfache Methode, um jede Nachricht auf Protokollebene auszugeben.
		logger.finest("FINEST Nachricht");
		logger.finer("FINER Nachricht");
		logger.fine("FEINE Nachricht");
		logger.config("CONFIG Nachricht");
		logger.info("INFO Nachricht");
		logger.warning("Warnmeldung");
		logger.severe("SEVERE Nachricht");
		
		//Zusätzlich zu der Methode zum Übergeben der Nachricht als Zeichenfolge bietet Supplier<String>Es gibt auch einen Weg zu passieren.
		Supplier<String> supplier = new Supplier<String>() {
			@Override
			public String get() {
				return "Nachricht liefern";
			}
		};
		logger.info(supplier);
		
		//Die Protokollausgabemethode beim Auftreten einer Ausnahme lautet wie folgt. Der als Argument übergebene Throwable-Stack-Trace wird ausgegeben.
		logger.log(Level.WARNING, "Ein Fehler ist aufgetreten.", new RuntimeException("Laufzeit Fehler"));
	}
}

Logger-Hierarchie

Logger haben eine hierarchische Struktur, die auf Namespaces basiert. Wenn Sie beispielsweise den folgenden Logger erstellen,

Logger logger = Logger.getLogger("com.sample.App");

Die hierarchische Struktur ist wie folgt. Der übergeordnete Logger für "com.sample.App" ist "com.sample" und der übergeordnete Logger für "com.sample" ist "com". Außerdem ist der übergeordnete Logger von com der Root-Logger.

Root
└─com
    └─sample
        └─App

Wenn der Logger eine Nachricht druckt, wird die Ausgabe auch an den übergeordneten Logger weitergegeben. Mit anderen Worten, wenn Sie im obigen Beispiel eine Nachricht an den Logger von "com.sample.App" ausgeben, wird die Nachricht von "com.sample", "com" bzw. dem Root-Logger ausgegeben.

Ich denke nicht, dass es einfach ist, es in Worten zu erklären, also schauen wir uns das Beispielprogramm an.

NameSpaceSample


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Holen Sie sich jeden Logger. Geben Sie im Logger-Namen ein leeres Zeichen an, um den Root-Logger abzurufen.
		Logger root = Logger.getLogger("");
		Logger com = Logger.getLogger("com");
		Logger sample = Logger.getLogger("com.sample");
		Logger app = Logger.getLogger("com.sample.App");
		
		// com.sample.App Eltern sind com.sample、com.Das übergeordnete Element von sample ist com, und das übergeordnete Element von com ist root logger.
		System.out.println(app.getParent() == sample);
		System.out.println(app.getParent().getParent() == com);
		System.out.println(app.getParent().getParent().getParent() == root);
		
		//Der Root-Logger hat ein übergeordnetes Element.
		System.out.println(root.getParent());
		
		//Legen Sie für jeden Logger einen Handler fest.
		Formatter formatter = new SimpleFormatter();
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		root.addHandler(rootHandler);
		rootHandler.setFormatter(formatter);
		
		Handler comHandler = new FileHandler("C:\\sample\\com.log");
		com.addHandler(comHandler);
		comHandler.setFormatter(formatter);
		
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		sample.addHandler(sampleHandler);
		sampleHandler.setFormatter(formatter);
		
		Handler appHandler = new FileHandler("C:\\sample\\App.log");
		app.addHandler(appHandler);
		appHandler.setFormatter(formatter);
		
		//Wenn Sie eine Nachricht mit der App ausgeben, wird auch eine Nachricht von jedem übergeordneten Logger ausgegeben.
		app.info("INFO Nachricht");
	}
}

Wenn das Beispielprogramm ausgeführt wird, werden die Protokolle in "root.log", "com.log", "sample.log" und "App.log" im Verzeichnis "C: \ sample" ausgegeben.

Verwendung des Filters

Ich habe eingeführt, wie die Protokollebene im Logger festgelegt und so gesteuert wird, dass nur Nachrichten über einer bestimmten Protokollebene ausgegeben werden. Wenn Sie jedoch eine detailliertere Steuerung wünschen, verwenden Sie die Klasse "Filter".

Filter filter = new Filter() {
	@Override
	public boolean isLoggable(LogRecord record) {
		return record.getMessage().contains("Anzahl der bearbeiteten Fälle=");
	}
};
logger.setFilter(filter);

Wenn Filter wie oben eingestellt ist, werden nur Protokolle ausgegeben, die "Anzahl der Prozesse =" in der Nachricht enthalten.

Legen Sie die Protokollstufe fest und filtern Sie im Handler

Die obige Erklärung zeigt, wie ein Protokollstufenfilter für einen Logger festgelegt wird. Tatsächlich können Protokollstufen und Filter auch in "Handler" festgelegt werden.

Das Beispielprogramm wird unten beschrieben.

FiltringSample


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class FiltringSample {
	
	public static void main(String[] arg) throws SecurityException, IOException {
		//Erstellen Sie einen Logger und legen Sie Handler und Formatierer fest
		Logger logger = Logger.getLogger("sample1");
		Handler handler = new FileHandler("C:\\sample\\sample.log");
		logger.addHandler(handler);
		handler.setFormatter(new SimpleFormatter());
		
		//Setzen Sie die Logger-Protokollstufe auf INFO
		logger.setLevel(Level.INFO);
		logger.info("Beispielnachricht");                          //Ausgabe
		
		//Setzen Sie einen Filter auf den Logger
		Filter filter1 = new Filter() {
			@Override
			public boolean isLoggable(LogRecord record) {
				return record.getMessage().contains("Anzahl der bearbeiteten Fälle=");
			}
		};
		logger.setFilter(filter1);
		logger.info("Beispielnachricht");                          //Nicht ausgegeben
		logger.info("Beispielnachricht,Anzahl der bearbeiteten Fälle=1");               //Ausgabe
		
		//Setzen Sie einen Filter auf den Handler
		Filter filter2 = (record) -> record.getMessage().contains("Anzahl der Updates=");
		handler.setFilter(filter2);
		logger.info("Beispielnachricht");                          //Nicht ausgegeben
		logger.info("Beispielnachricht,Anzahl der bearbeiteten Fälle=1");               //Nicht ausgegeben
		logger.info("Beispielnachricht,Anzahl der bearbeiteten Fälle=1,Anzahl der Updates=1");    //Ausgabe
		
		//Legen Sie die Protokollstufe im Handler fest
		handler.setLevel(Level.WARNING);
		logger.info("Beispielnachricht");                          //Nicht ausgegeben
		logger.info("Beispielnachricht,Anzahl der bearbeiteten Fälle=1");               //Nicht ausgegeben
		logger.info("Beispielnachricht,Anzahl der bearbeiteten Fälle=1,Anzahl der Updates=1");    //Nicht ausgegeben
		logger.warning("Warnmeldung,Anzahl der bearbeiteten Fälle=1,Anzahl der Updates=1");   //Ausgabe
	}
}

Wenn Sie die obigen Schritte ausführen, können Sie sehen, dass die Protokollausgabe durch die Protokollstufe und den Filtersatz für den Logger und den Handler begrenzt ist.

Protokollausgabesteuerung in der Loggerhierarchie

Wir haben oben eingeführt, dass Logger eine hierarchische Struktur haben und dass eine Nachricht, die an den Logger ausgegeben wird, an den übergeordneten Logger weitergegeben wird. Tatsächlich gibt es in diesem Ausbreitungsmechanismus eine Falle, und wenn Sie den Mechanismus nicht richtig verstehen, können Sie im Topf stecken bleiben. (Ich passe in ...) Es kann schwierig sein zu verstehen, selbst wenn Sie es in Worten erklären, aber sobald Sie es in Worten erklären, sind die Spezifikationen für die Weitergabe an den übergeordneten Logger wie folgt.

Ja, ich denke es ist schwer zu verstehen. Ich denke, Sie können dies schneller verstehen, wenn Sie direkt auf die Logik schauen. Grob gesagt entspricht die Protokollausgabelogik der folgenden Abbildung.

フローチャート.png

Hast du verstanden? Der im Logger festgelegte Filter auf Protokollebene wird nur beim ersten Logger überprüft, der den Anruf empfängt, während er aktiviert ist. Alle Handler überprüfen den im Handler festgelegten Protokollstufenfilter.

Zwei Beispiele, um dies zu bestätigen, werden unten beschrieben.

NameSpaceSample2


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample2 {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Holen Sie sich 3 Logger. Stellen Sie den Handler und den Formatierer ein.
		Logger root = Logger.getLogger("");
		Logger sample = Logger.getLogger("sample");
		Logger loggerTreeSample = Logger.getLogger("sample.NameSpaceSample2");
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		Handler NameSpaceSample2Handler = new FileHandler("C:\\sample\\NameSpaceSample2.log");
		Formatter formatter = new SimpleFormatter();
		rootHandler.setFormatter(formatter);
		sampleHandler.setFormatter(formatter);
		NameSpaceSample2Handler.setFormatter(formatter);
		root.addHandler(rootHandler);
		sample.addHandler(sampleHandler);
		loggerTreeSample.addHandler(NameSpaceSample2Handler);
		
		//Stellen Sie die Protokollstufe auf den Logger ein.
		root.setLevel(Level.WARNING);
		sample.setLevel(Level.INFO);
		loggerTreeSample.setLevel(Level.FINE);

		//Der Handler ist so eingestellt, dass alle Protokollebenen zulässig sind. (Niveau.Durch Festlegen von ALL können alle Nachrichten auf Protokollebene ausgegeben werden. )
		rootHandler.setLevel(Level.ALL);
		sampleHandler.setLevel(Level.ALL);
		NameSpaceSample2Handler.setLevel(Level.ALL);
		
		//Ausgabeprotokoll
		root.fine("Aufruf von root.FEINE Nachricht");
		root.info("Aufruf von root.INFO Nachricht");
		root.warning("Aufruf von root.Warnmeldung");
		sample.fine("Aus Probe senden.FEINE Nachricht");
		sample.info("Aus Probe senden.INFO Nachricht");
		sample.warning("Aus Probe senden.Warnmeldung");
		loggerTreeSample.fine("Wird von NameSpaceSample2Handler aufgerufen.FEINE Nachricht");
		loggerTreeSample.info("Wird von NameSpaceSample2Handler aufgerufen.INFO Nachricht");
		loggerTreeSample.warning("Wird von NameSpaceSample2Handler aufgerufen.Warnmeldung");
	}
}

Wenn das oben Gesagte ausgeführt wird, lautet die von loggerTreeSample.fine (...) ausgegebene Nachricht C: \\ sample \\ root, obwohl sie als root.setLevel (Level.WARNING); festgelegt ist. Sie können sehen, dass es in .log ausgegeben wird.

Hier ist ein weiteres Beispiel. Der einzige Unterschied zum obigen Beispiel besteht in der Einstellung der Protokollstufe.

NameSpaceSample3


package sample;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class NameSpaceSample3 {

	public static void main(String[] arg) throws SecurityException, IOException {
		//Holen Sie sich 3 Logger. Stellen Sie den Handler und den Formatierer ein.
		Logger root = Logger.getLogger("");
		Logger sample = Logger.getLogger("sample");
		Logger loggerTreeSample = Logger.getLogger("sample.NameSpaceSample2");
		Handler rootHandler = new FileHandler("C:\\sample\\root.log");
		Handler sampleHandler = new FileHandler("C:\\sample\\sample.log");
		Handler NameSpaceSample3Handler = new FileHandler("C:\\sample\\NameSpaceSample3.log");
		Formatter formatter = new SimpleFormatter();
		rootHandler.setFormatter(formatter);
		sampleHandler.setFormatter(formatter);
		NameSpaceSample3Handler.setFormatter(formatter);
		root.addHandler(rootHandler);
		sample.addHandler(sampleHandler);
		loggerTreeSample.addHandler(NameSpaceSample3Handler);
		
		//Der Logger ist so eingestellt, dass alle Log-Ebenen zugelassen werden. (Niveau.Durch Festlegen von ALL können alle Nachrichten auf Protokollebene ausgegeben werden. )
		root.setLevel(Level.ALL);
		sample.setLevel(Level.ALL);
		loggerTreeSample.setLevel(Level.ALL);

		//Legen Sie die Protokollstufe im Handler fest.
		rootHandler.setLevel(Level.WARNING);
		sampleHandler.setLevel(Level.INFO);
		NameSpaceSample3Handler.setLevel(Level.FINE);
		
		//Ausgabeprotokoll
		root.fine("Aufruf von root.FEINE Nachricht");
		root.info("Aufruf von root.INFO Nachricht");
		root.warning("Aufruf von root.Warnmeldung");
		sample.fine("Aus Probe senden.FEINE Nachricht");
		sample.info("Aus Probe senden.INFO Nachricht");
		sample.warning("Aus Probe senden.Warnmeldung");
		loggerTreeSample.fine("Wird von NameSpaceSample3Handler aufgerufen.FEINE Nachricht");
		loggerTreeSample.info("Wird von NameSpaceSample3Handler aufgerufen.INFO Nachricht");
		loggerTreeSample.warning("Wird von NameSpaceSample3Handler aufgerufen.Warnmeldung");
	}
}

Wenn Sie die obigen Schritte ausführen, können Sie sehen, dass nur Protokolle der WARNING-Ebene an C: \\ sample \\ root.log ausgegeben werden.

Einstellungsdatei lesen

Wie Sie vielleicht in den Beispielprogrammen bisher gesehen haben, kann es mühsam sein, viel Code zum Einrichten von Loggern und Handlern zu schreiben. Schließlich möchte ich den Einstellungsteil aus dem Programm herausschieben und in die Einstellungsdatei schreiben. Daher besteht die nächste Methode darin, die Einstellungsdatei von außen zu lesen.

Die Methode zum Lesen der Einstellungsdatei aus dem Programm lautet wie folgt. Dieses Mal habe ich versucht, "logging.properties" zu lesen, die sich im selben Klassenpfad des Beispielprogramms befinden. Die Konfigurationsdatei sollte im Format "java.util.Properties" gelesen werden.

LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));

Die Beispieleinstellungsdatei lautet wie folgt. Eine ausführliche Erklärung finden Sie unter "{java.home} \ lib \ logging.properties".

logging.properties


#Einstellung der Protokollstufe des Root-Logger-Handlers ConsoleHandler hat einen Standardfehler(System.err)Geben Sie das Protokoll an aus.
handlers=java.util.logging.ConsoleHandler
.level=INFO

#Logger, der im Beispielprogramm verwendet wird"sample.SettingFileSample"Einstellungen von
sample.SettingFileSample.level=FINE
sample.SettingFileSample.handlers=java.util.logging.FileHandler

#ConsoleHandler-Einstellungen
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

#FileHandler-Einstellungen
java.util.logging.FileHandler.pattern=C:/sample/sample.log
java.util.logging.FileHandler.limit=1000
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

Das Beispielprogramm, das die obige Einstellungsdatei verwendet, wird unten beschrieben.

SettingFileSample


package sample;

import java.io.IOException;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class SettingFileSample {

	public static void main(String[] arg) throws SecurityException, IOException {
		LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));

		Logger logger = Logger.getLogger("sample.SettingFileSample");
		logger.finer("FINER Nachricht");
		logger.fine("FEINE Nachricht");
		logger.info("INFO Nachricht");
	}
}

Es ist ordentlich, weil es keine Logger- oder Handler-Einstellungen gibt.

Verwendung von ResourceBundle mit Logger

java.util.logging kann auch die Internationalisierung mit ResourceBundle unterstützen. Das Beispielprogramm wird unten beschrieben. Das Beispiel verwendet resource_ja.properties und resource_en.properties im selben Klassenpfad wie die Java-Klasse.

ResourceBundleSample


package sample;

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Logger;

public class ResourceBundleSample {

	public static void main(String[] arg) {
		Logger lggr = Logger.getLogger(ResourceBundleSample.class.getName());
		lggr.setResourceBundle(ResourceBundle.getBundle("sample.resource", Locale.JAPANESE));
		lggr.info("ID1");
		
		lggr.setResourceBundle(ResourceBundle.getBundle("sample.resource", Locale.ENGLISH));
		lggr.info("ID1");
	}
}

resource_ja.properties


ID1=Japanische Nachricht

resource_en.properties


ID1=english message

Wenn das Beispielprogramm ausgeführt wird, wird das erste Protokoll als "japanische Nachricht" und das zweite Protokoll als "englische Nachricht" ausgegeben.

Verwendung von Security Manager mit Logger

Wenn Security Manager aktiviert ist, können die Logger-Einstellungen nicht programmgesteuert geändert werden. Wenn das folgende Beispielprogramm mit aktiviertem Security Manager ausgeführt wird, wird "AccessControlException" ausgeführt.

LoggingPermissionSample


package sample;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingPermissionSample {
	
	public static void main(String[] arg) {
		Logger lg = Logger.getLogger("");
		lg.setLevel(Level.FINE);
		lg.fine("fine message");
		lg.info("info message");
	}
}

Schreiben Sie Folgendes in Ihre Richtliniendatei, um Änderungen am Logger zuzulassen, wenn Security Manager aktiviert ist: Einzelheiten finden Sie im Javadoc von "LoggerPermission".

java.policy


grant {
        permission java.util.logging.LoggingPermission "control", "";
}

Geben Sie zum Aktivieren des Sicherheitsmanagers im VM-Argument "java.security.manager" an, wie unten gezeigt. Um die Richtliniendatei explizit anzugeben, geben Sie im VM-Argument "java.security.policy" an, wie unten gezeigt.

java -Djava.security.manager -Djava.security.policy=Beispiel für einen Richtliniendateipfad.LoggingPermissionSample

Recommended Posts

Verwendung von java.util.logging
Verwendung von Map
Wie benutzt man rbenv?
Verwendung mit_option
Verwendung von fields_for
Verwendung der Karte
Verwendung von collection_select
Wie benutzt man Twitter4J
Wie benutzt man active_hash! !!
Verwendung von MapStruct
Verwendung von TreeSet
[Verwendung des Etiketts]
Wie man Identität benutzt
Wie man Hash benutzt
Verwendung von Dozer.mapper
Wie benutzt man Gradle?
Verwendung von org.immutables
Verwendung von java.util.stream.Collector
Verwendung von VisualVM
Verwendung von Map
Verwendung der Ketten-API
[Java] Verwendung von Map
Verwendung der Warteschlange mit Priorität
[Rails] Verwendung von Enum
Verwendung von Java Optional
Verwendung von JUnit (Anfänger)
Verwendung von Ruby return
[Rails] Verwendung von Enum
Verwendung von @Builder (Lombok)
Verwendung der Java-Klasse
Wie man Big Decimal benutzt
[Java] Verwendung von removeAll ()
Verwendung von String [] args
Verwendung von Rails Join
Verwendung von Java Map
Ruby: Wie man Cookies benutzt
Verwendung von abhängigen :: zerstören
Verwendung von Eclipse Debug_Shell
Verwendung von Apache POI
[Rails] Verwendung der Validierung
Verwendung von Java-Variablen
[Rails] So verwenden Sie authenticate_user!
Verwendung von GC Viewer
Wie man Lombok jetzt benutzt
[Erstellen] Verwendung von JUnit
[Schienen] Verwendung von Scope
Verwendung der link_to-Methode
[Rails] Wie man Edelstein "devise" benutzt
Wie man Lombok im Frühling benutzt
Verwendung von StringBurrer und Arrays.toString.
Verwendung des Arrays (persönliches Memorandum)