369 Stimmen

Was ist die Initialisierung der doppelten Klammer in Java?

Was ist die Syntax für die Initialisierung der doppelten Klammer ( {{ ... }} ) in Java?

16voto

ctomek Punkte 1616

1- Es gibt keine doppelten Klammern:
Ich möchte darauf hinweisen, dass es so etwas wie eine doppelte Klammerinitialisierung nicht gibt. Es gibt nur normale traditionelle eine Klammer initializaition Block. Der zweite Klammerblock hat nichts mit der Initialisierung zu tun. Antworten sagen, dass diese zwei Klammern etwas initialisieren, aber das ist nicht so.

2- Es geht nicht nur um anonyme Klassen, sondern um alle Klassen:
Fast alle Antworten besagen, dass es sich um eine Sache handelt, die bei der Erstellung anonymer innerer Klassen verwendet wird. Ich denke, dass Leute, die diese Antworten lesen, den Eindruck bekommen, dass dies nur bei der Erstellung anonymer innerer Klassen verwendet wird. Es wird aber in allen Klassen verwendet. Wenn man diese Antworten liest, sieht es so aus, als ob es sich um eine brandneue Spezialfunktion für anonyme Klassen handelt, und ich denke, das ist irreführend.

3- Es geht nur darum, Klammern hintereinander zu setzen, kein neues Konzept:
Weiterführend geht es in dieser Frage um die Situation, wenn die zweite Eröffnungsklammer direkt nach der ersten Eröffnungsklammer liegt. Bei der Verwendung in einer normalen Klasse befindet sich normalerweise etwas Code zwischen zwei Klammern, aber es ist völlig dasselbe. Es ist also eine Frage der Platzierung der Klammern. Ich denke also, wir sollten nicht sagen, dass dies eine neue aufregende Sache ist, denn das ist die Sache, die wir alle kennen, nur eben mit etwas Code zwischen den Klammern geschrieben. Wir sollten kein neues Konzept namens "doppelte Klammerinitialisierung" schaffen.

4- Die Erstellung verschachtelter anonymer Klassen hat nichts mit zwei geschweiften Klammern zu tun:
Ich stimme nicht mit dem Argument überein, dass Sie zu viele anonyme Klassen erstellen. Man erstellt sie nicht, weil man einen Initialisierungsblock verwendet, sondern weil man sie einfach erstellt. Sie würden auch erstellt werden, wenn Sie keine Initialisierung mit zwei geschweiften Klammern verwenden würden, so dass diese Probleme auch ohne Initialisierung auftreten würden... Die Initialisierung ist nicht der Faktor, der initialisierte Objekte erzeugt.

Außerdem sollten wir nicht über das Problem sprechen, das durch die Verwendung dieser nicht existierenden Sache "doppelte Klammerinitialisierung" oder sogar durch die normale Initialisierung mit einer Klammer entsteht, da die beschriebenen Probleme nur durch die Erstellung einer anonymen Klasse entstehen und nichts mit der ursprünglichen Frage zu tun haben. Aber alle Antworten vermitteln dem Leser den Eindruck, dass es nicht an der Erstellung anonymer Klassen liegt, sondern an dieser bösen (nicht existierenden) Sache namens "double brace initialization".

11voto

Um alle negativen Auswirkungen der doppelten Klammerinitialisierung zu vermeiden, wie z. B.:

  1. Gebrochene "Gleich"-Kompatibilität.
  2. Bei der Verwendung von Direktzuweisungen werden keine Kontrollen durchgeführt.
  3. Mögliche Speicherlecks.

die nächsten Dinge tun:

  1. Erstellen Sie eine eigene Klasse "Builder" speziell für die Initialisierung von Doppelklammern.
  2. Deklarieren Sie Felder mit Standardwerten.
  3. Fügen Sie eine Methode zur Objekterzeugung in diese Klasse ein.

Beispiel:

public class MyClass {
    public static class Builder {
        public int    first  = -1        ;
        public double second = Double.NaN;
        public String third  = null      ;

        public MyClass create() {
            return new MyClass(first, second, third);
        }
    }

    protected final int    first ;
    protected final double second;
    protected final String third ;

    protected MyClass(
        int    first ,
        double second,
        String third
    ) {
        this.first = first ;
        this.second= second;
        this.third = third ;
    }

    public int    first () { return first ; }
    public double second() { return second; }
    public String third () { return third ; }
}

Verwendung:

MyClass my = new MyClass.Builder(){{ first = 1; third = "3"; }}.create();

Vorteile:

  1. Einfach zu verwenden.
  2. Brechen Sie nicht die Kompatibilität von "gleich".
  3. Sie können in der Erstellungsmethode Prüfungen durchführen.
  4. Keine Speicherlecks.

Benachteiligungen:

  • Keine.

Und als Ergebnis haben wir das einfachste Java-Builder-Muster überhaupt.

Alle Beispiele finden Sie auf github: java-sf-builder-einfaches-beispiel

5voto

Mikhail Kholodkov Punkte 20422

Wie von @Lukas Eder hervorgehoben Die Initialisierung von Sammlungen in doppelten Klammern muss vermieden werden.

Es wird eine anonyme innere Klasse erstellt, und da alle internen Klassen einen Verweis auf die übergeordnete Instanz behalten, kann - und wird zu 99 % wahrscheinlich - die Garbage Collection verhindert werden, wenn diese Sammlungsobjekte von mehr Objekten als nur dem deklarierenden Objekt referenziert werden.

Java 9 hat Komfortmethoden eingeführt List.of , Set.of und Map.of die stattdessen verwendet werden sollte. Sie sind schneller und effizienter als der Double-Brace-Initialisierer.

4voto

miku Punkte 170688

Es ist - neben anderen Verwendungen - eine Abkürzung für die Initialisierung von Sammlungen. Mehr erfahren ...

4voto

dhblah Punkte 9351

Sie meinen so etwas wie das hier?

List<String> blah = new ArrayList<String>(){{add("asdfa");add("bbb");}};

Es handelt sich um eine Array-Listeninitialisierung in der Erstellungszeit (Hack)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X