JavaRush /Java-Blog /Random-DE /Initialisierung mit doppelter Klammer
Joysi
Level 41

Initialisierung mit doppelter Klammer

Veröffentlicht in der Gruppe Random-DE

1. Initialisierung mit doppelter Klammer

Die Initialisierung mit doppelten Klammern ( im Folgenden als Initialisierung mit doppelten Klammern bezeichnet ) ist ein Java-Tool zum gleichzeitigen Erstellen von Sammlungen wie Listen, Mengen und Karten mit deren Deklaration.
Initialisierung mit doppelter Klammer – 1
Wenn Sie Listen mit festen Elementen benötigen, z. B. eine Liste unterstützter Produkte oder Währungen, verbessert die Deklaration der Liste gleichzeitig mit der Initialisierung die Lesbarkeit des Codes. Aus diesem Grund erfreut sich die Initialisierung mit doppelten Klammern immer größerer Beliebtheit, da es keine anderen Standardmethoden zum Erstellen von Sammlungen mit gleichzeitiger Initialisierung im Code gibt. Leider unterstützt Java im Gegensatz zu anderen Programmiersprachen keine Sammlungen von Literalen. Aufgrund dieser Einschränkung zwingt uns das Erstellen einer unmodifiableList auch nur mit einer kleinen Anzahl von Elementen dazu, viele Codezeilen in Form wiederholter Aufrufe zu schreiben, add()um die gewünschten Elemente mit abschließendem Wrapping hinzuzufügen:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Dies ist eine unnötig redundante Beschreibung, die vereinfacht werden könnte. Lassen Sie uns statische Listen auf eine für uns bequeme Weise füllen, nämlich direkt in statischen Blöcken während der Initialisierung. Dabei Double bracehilft uns die Initialisierung, sodass wir alles in eine Zeile schreiben können:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
Ebenso Double bracehilft uns die Initialisierung dabei, Werte einzugeben und HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
Das sieht alles so elegant aus, hat aber seine Nachteile, die die Initialisierung mit doppelten Klammern zu einem Anti-Muster machen. Wir werden sie uns im nächsten Kapitel genauer ansehen.

Vor- und Nachteile der Initialisierung mit doppelter Klammer.

DoubleBei der Klammerinitialisierung wird eine anonyme innere Klasse erstellt . Was jedoch zunächst an der Oberfläche verborgen bleibt, Double bracewird durch die Initialisierung bei jeder Verwendung einer Klasse mit einer weiteren Initialisierung ihrer Instanz erstellt. Darüber hinaus wird ein versteckter Verweis auf diese private Klasse verwendet, was zu möglichen Speicherlecks führen kann. Sie können den Ghost-Operator auch nicht für Generika verwenden (Diamond-Operator < >), da wir nicht auf das Innere einer anonymen Klasse zugreifen können.
(Vom Übersetzer: Noch einmal ausführlicher:
Nach der ersten {wird eine interne anonyme Klasse erstellt, nach der zweiten {erfolgt die Initialisierung beim Erstellen einer Instanz der Klasse, in der wir Zugriff auf die Felder und Methoden der externen ( relativ zur anonymen) Klasse.)
Vorteile:
  1. Zeilen im Code reduzieren
  2. Erstellung und Initialisierung in einem Ausdruck.
Nachteile:
  1. Erstellen einer anonymen Klasse, die vor Ihnen verborgen bleibt.
  2. Das kostet uns bei jeder Nutzung zusätzliche Kosten für die Instanz.
  3. Jedes Mal wird ein versteckter Verweis darauf erstellt, was zu Speicherverlusten führen kann.
Urteil: Aufgrund der oben genannten Nachteile und der Existenz von Alternativen zur doppelten Klammer gilt die Initialisierung in der Java-Welt als Anti-Pattern. Rette das Kätzchen

Alternativen zur Initialisierung mit doppelten Klammern in Java

Die gute Nachricht ist, dass es in Java andere Möglichkeiten gibt, dieselben Ziele zu erreichen. Wir können die Erstellung und Initialisierung einer ArrayList mithilfe des Copy-Konstruktors aus der Collection-Klasse in einer Codezeile implementieren, wie unten gezeigt:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()gibt uns eine Liste fester Länge zurück, die an ArrayListden Kopierkonstruktor übergeben wird. Beachten Sie den Unterschied zwischen Listen fester Länge, die von Arrays.asList()und zurückgegeben werden Collections.unmodifiableList(): Sie können keine Elemente ArrayListvon - hinzufügen oder entfernen, aber Sie können ein Element anhand des Index ändern , indem set()Sie verwenden, was bei einer von zurückgegebenen Liste nicht möglich ist Collections.unmodifiableList(). Wenn Sie eine kleine Liste erhalten möchten, ist dies die beste Möglichkeit, obwohl sie für andere Sammlungen weniger transparent ist , sodass Sie sie vor der Erstellung von -a Seterstellen müssen . Dies ist jedoch immer noch besser als die Initialisierung mit doppelten Klammern, da in diesem Fall nicht bei jeder Verwendung eine zusätzliche interne anonyme Klasse erstellt wird. Wenn Sie Java 8 ausführen, steht Ihnen eine andere alternative Methode zur Verfügung. Die JDK 8 Stream API hilft Ihnen beim Erstellen kleiner Sammlungen, indem Ausgabemethoden in einer Sammlung kombiniert werden : ListSetStream FactoryList
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
SetSie können stattdessen Collectors.toSet()die folgende Methode verwenden Collectors.toList():
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
Übrigens Stream collectgarantieren Methoden nicht, dass die von ihnen generierten Sammlungen vor Änderungen geschützt sind. In Java 8 sind die von ihnen zurückgegebenen Sammlungen (z. B. - ArrayList, HashSetund HashMap) recht häufig (wir können sie ändern), aber dieser Umstand wird möglicherweise in zukünftigen JDK-Versionen korrigiert. Das ist fürs Erste alles über Double bracedie Initialisierung in Java. Diese Vorlage ist für Tests und Demos geeignet, aber nicht gut genug für den Produktionseinsatz. Aufgrund seiner inhärenten Nachteile ist die Double-Brace-Initialisierung heutzutage zu einem Anti-Pattern geworden, insbesondere angesichts der verfügbaren Alternativen. Ich selbst verwende diese Konstruktion immer noch, um statische Karten zu initialisieren, und das war’s. Denn Listich bevorzuge das Erstellen Collectionsdurch Kombinieren mit dem Erstellen Array.asListin seinem Konstruktor. Und wenn ich Java 8 verwende – ein Design mit der Stream-API und collect(). Verwandte Artikel: Wenn Ihnen dieses Tutorial gefallen hat und Sie mehr über Java-Programmiermuster, -Prinzipien und Best Practices erfahren möchten, können Sie sich auch die anderen Artikel auf unserer Website ansehen . Empfohlene Lektüre: Wenn Sie mehr über Muster und Best Practices erfahren möchten, sollten Sie „ Effective Programming“ von Joshua Bloch lesen . Kein Buch kann es ersetzen. Und wenn Sie bereits Java-Kenntnisse haben und ein Buch über Designmuster suchen, dessen humorvoller Präsentationsstil interessant und leicht zu lesen ist, achten Sie auf „Head First“. Designmuster" .
Vom Übersetzer: Ich habe bewusst einen Link zu Blochs Originalbuch bereitgestellt, da dessen Übersetzung ins Russische fehlgeschlagen ist (z. B. Builder = Konstrukteur).
Übersetzung des Artikels Was ist Double Brace Initialization in Java? Anti-Pattern-Beispiel (veröffentlicht im Oktober 2015).
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION