Was ist Double-Brace-Initialisierung in Java?
Was ist Double Brace initialization syntax ({{ ... }}
) in Java?
Siehe stackoverflow.com/questions/1372113/...
Siehe auch stackoverflow.com/q/924285/45935
Double-Brace-Initialisierung ist eine sehr gefährliche Funktion und sollte verwendet werden, richtig. Es kann brechen gleich Vertrag und stellen knifflige memory-leaks. Dieser Artikel beschreibt die details.
Es ist anscheinend tötet auch die kleinen Kätzchen 😉 stackoverflow.com/a/27521360/1678392
Siehe auch stackoverflow.com/q/924285/45935
Double-Brace-Initialisierung ist eine sehr gefährliche Funktion und sollte verwendet werden, richtig. Es kann brechen gleich Vertrag und stellen knifflige memory-leaks. Dieser Artikel beschreibt die details.
Es ist anscheinend tötet auch die kleinen Kätzchen 😉 stackoverflow.com/a/27521360/1678392
InformationsquelleAutor sgokhales | 2009-12-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Double-brace-Initialisierung erstellt eine anonyme Klasse, die von der angegebenen Klasse (die äußeren geschweiften Klammern), und bietet eine initialiser block innerhalb dieser Klasse (die innere Klammern). z.B.
Beachten Sie, dass ein Effekt, der mit diesem double-brace-Initialisierung ist, dass Sie bei der Erstellung einer anonymen inneren Klassen. Die erstellte Klasse ist, hat eine implizite
this
Zeiger auf die umgebende äußere Klasse. Während normalerweise kein problem, es kann Trauer in einigen Umständen, z.B. wenn serialising oder Müll zu sammeln, und es lohnt sich in diesem Bewußtsein."Magic syntax" wie diese existiert in vielen Sprachen, zum Beispiel fast alle C-ähnlichen Sprachen die "0" syntax "x --> 0" in for-Schleifen, die nur "x-- > 0" mit seltsamen Raum Platzierung.
Wir können nur folgern, dass "double brace initialization" existiert nicht auf seine eigene, ist es nur eine Kombination der Schaffung einer anonyme Klasse und Initialisierung-block, die, sobald Sie kombiniert werden, aussieht wie eine syntaktische Konstrukt, aber in Wirklichkeit ist es das nicht.
InformationsquelleAutor Brian Agnew
Jedes mal, wenn jemand nutzt double-brace-Initialisierung, ein Kätzchen getötet wird.
Abgesehen von der syntax eher ungewöhnlich und nicht wirklich idiomatische (Geschmack läßt sich streiten, natürlich), Sie sind unnötig Schaffung von zwei erhebliche Probleme bei Ihrer Anwendung, die habe ich erst vor kurzem darüber gebloggt, in mehr detail hier.
1. Sie erstellen mit viel zu vielen anonymen Klassen
Jedes mal, wenn Sie double-brace-Initialisierung einer neuen Klasse. E. g. in diesem Beispiel:
... produzieren diese Klassen:
Das ist schon ein bisschen Aufwand für Ihre classloader - für nichts! Natürlich ist es nicht viel, die Initialisierung Zeit, wenn Sie es einmal tun. Aber wenn Sie dies tun 20'000 mal in Ihrem gesamten Unternehmen Anwendung... alle, dass heap-Speicher nur für ein etwas "syntax-Zucker"?
2. Sie sind potenziell erstellen einen Speicherverlust!
Wenn Sie den obigen code, und der Rendite, die anzeigen von einer Methode, den Anrufer von dieser Methode möglicherweise ahnungslos halten sehr starke Ressourcen, die nicht von der garbage Collection freigegeben. Betrachten Sie das folgende Beispiel:
Den zurückgegebenen
Map
enthält nun eine Referenz auf die umschließende InstanzReallyHeavyObject
. Sie wollen wahrscheinlich nicht zu riskieren, dass:Bild von http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. Sie können vorgeben, dass Java-map-Literale
Zur Beantwortung Ihrer eigentlichen Frage, die Menschen haben mit dieser syntax zu behaupten, dass Java hat so etwas wie map-Literale, ähnlich dem bereits existierenden array-Literale:
Einige Leute finden diese syntaktisch anregend.
Es hängt vom Kontext natürlich.
Nicht, es bleibt eine gültige und nette Art zu erklären, statische Karten? Wenn eine HashMap initialisiert
{{...}}
und erklärtstatic
Feld, es sollte nicht möglich memory leak, nur eine anonyme Klasse und keine geschlossene Instanz Verweise, richtig?Ja, 2) und 3) gelten nicht für dann nur 1). Zum Glück, mit Java-9, gibt es schließlich
Map.of()
für diesen Zweck, so dass Sie eine bessere LösungEs mag auch erwähnenswert sein, dass die inneren Landkarten haben auch Verweise auf die äußeren Karten und damit indirekt zu
ReallyHeavyObject
. Auch, anonyme innere Klassen, Erfassung aller lokalen Variablen, die innerhalb der Klasse Körper, so dass, wenn Sie nicht nur mit Konstanten initialisieren, Sammlungen oder Karten mit diesem Muster, die die innere Klasse Instanzen erfassen Sie alle und weiterhin auf Sie verweisen, auch wenn tatsächlich aus der Sammlung entfernt oder gekennzeichnet. So ist es, Fall, diese Fälle brauchen nicht nur doppelt so notwendige Speicher für die Hinweise, aber haben ein weiteres Speicher-Leck in dieser Hinsicht.InformationsquelleAutor Lukas Eder
Zum Beispiel:
, Wie es funktioniert
Ersten Klammer erstellt eine neue Anonyme Innere Klasse. Diese inneren Klassen sind in der Lage auf das Verhalten der übergeordneten Klasse. Also, in unserem Fall, wir sind eigentlich das erstellen einer Subklasse von HashSet-Klasse, so dass diese innere Klasse ist in der Lage mit put () - Methode.
Und Zweite Satz von Klammern sind nichts anderes als Instanz Initialisierungen. Wenn Sie daran erinnern, Kern-java-Konzepte-dann können Sie ganz einfach zuordnen Instanz-Initialisierer Blöcke mit statischen Initialisierungen, die durch ähnliche Klammer wie struct. Nur der Unterschied ist, dass der statische Initialisierer wird Hinzugefügt mit dem static-Schlüsselwort, und wird nur einmal ausgeführt, egal wie viele Objekte Sie erstellen.
mehr
InformationsquelleAutor Premraj
Für ein Spaß-Anwendung der double-brace-Initialisierung, siehe hier Dwemthy Array in Java.
Einen Auszug
Und jetzt, bereit sein, für die
BattleOfGrottoOfSausageSmells
... klobige Speck!InformationsquelleAutor akuhn
Ich denke, es ist wichtig zu betonen, dass es gibt keine solche Sache wie "Double Brace initialization" in der Java -. Oracle-web-site nicht diesen Begriff. In diesem Beispiel gibt es zwei Funktionen gemeinsam verwendet: anonyme Klasse und Initialisierung von block. Scheint, wie die alten block-Initialisierer wurde vergessen, die von den Entwicklern dazu führen, dass einige Verwirrung in diesem Thema. Zitat von Oracle docs:
Initialisierer blocks für die Instanz-Variablen, die genauso Aussehen wie statische Initialisierer Blöcke, aber ohne das Schlüsselwort static:
InformationsquelleAutor Alex T
Zu vermeiden, werden alle negativen Auswirkungen der double-brace-Initialisierung, wie:
Nächstes tun Dinge:
Beispiel:
Verwendung:
Vorteile:
Nachteile:
Und, als Ergebnis, haben wir die einfachste java-builder pattern je.
Siehe alle Beispiele auf github: java-sf-builder-einfache-Beispiel
InformationsquelleAutor Boris Podchezertsev
1 - Es gibt keine solche Sache als doppelt geschweiften Klammern:
Ich möchte darauf hinweisen, dass es keine solche Sache als double-brace-Initialisierung. Es ist nur normal, traditionell eine Stütze initializaition block. Zweite geschweifte Klammern block hat nichts zu tun mit der Initialisierung. Antworten sagen, dass die beiden geschweiften Klammern initialisieren etwas, aber es ist nicht so.
2 - Es geht nicht nur um anonyme Klassen aber alle Klassen:
Fast alle Antworten sprechen, dass es ist eine Sache, die Sie beim anlegen von anonymen inneren Klassen. Ich denke, dass die Menschen mit der Lektüre dieser Antworten den Eindruck, dass dies nur beim erstellen von anonymen inneren Klassen. Aber es wird in allen Klassen. Lesen die Antworten, es sieht aus wie einige BRANDNEUE Besonderheit gewidmet anonyme Klassen, und ich denke, das ist irreführend.
3 - Der Zweck ist nur über die Platzierung von Klammern nach jeder anderen, nicht neuen Konzept:
Weiter zu gehen, dieser Frage Gespräche über die situation bei der zweiten öffnenden Klammer ist nur nach der ersten öffnenden Klammer. Wenn in der normal-Klasse in der Regel gibt es einige code zwischen den beiden geschweiften Klammern, aber es ist völlig das gleiche. So ist es eine Frage der Platzierung von Klammern. Also ich denke, wir sollten nicht sagen, dass dies ist eine neue, spannende Sache, denn das ist die Sache, die wir alle kennen, aber einfach geschrieben, mit einigen code zwischen den Klammern. Wir sollten nicht neue Konzept namens "double brace initialization".
4 - Erstellen von verschachtelten anonymen Klassen nichts zu tun hat mit zwei Klammern:
Ich bin nicht einverstanden mit einer Argumentation, die Sie erstellen, zu viele anonyme Klassen. Sie sind sich nicht erstellen, weil eine Initialisierungs-block, aber nur, weil Sie Sie erstellen. Sie würden erstellt werden, auch wenn Sie nicht verwenden Sie zwei geschweiften Klammern der Initialisierung, so dass diese Probleme würden auch auftreten, ohne Initialisierung Initialisierung... ist nicht der Faktor, der schafft initialisierte Objekte.
InformationsquelleAutor ctomek
Es ist - neben anderen Verwendungen - eine Abkürzung für die Initialisierung Sammlungen. Erfahren Sie mehr ...
InformationsquelleAutor miku
meinst du so etwas?
es ist eine array-Liste Initialisierungs-im Zeitpunkt der Erstellung (hack)
InformationsquelleAutor dhblah
Können Sie einige Java-Anweisungen als Schleife zu initialisieren Sammlung:
Aber dieser Fall Auswirkungen auf die Leistung haben, prüfen Sie diese Diskussion
InformationsquelleAutor Anton Dozortsev
Double-brace-Initialisierung nutzt die inneren Klassen syntax. Angenommen, Sie möchten zum erstellen einer array-Liste und übergeben Sie es an eine Methode:
Wenn Sie nicht brauchen, das array wieder in die Liste, es wäre schön, um es anonym. Aber wie kann man dann fügen Sie die Elemente? (double-brace-Initialisierung kommt hier) Hier ist, wie:
Beachten Sie die doppelten geschweiften Klammern. Die äußeren Klammern stellen eine anonyme Unterklasse von
ArrayList
. Die inneren geschweiften Klammern sind ein Objekt-Bau-block.InformationsquelleAutor hamza belmellouki
Wie bereits von @Lukas Eder doppelten geschweiften Klammern bei der Initialisierung von collections müssen vermieden werden.
Es erzeugt eine anonyme innere Klasse, und da alle internen Klassen halten eine Referenz auf das parent-Instanz, die es kann - und zu 99% wird wahrscheinlich verhindern garbage collection, wenn diese Sammlung Objekte referenziert werden, indem mehr Objekte als nur die Deklaration.
Java 9 vorgestellt hat, convenience-Methoden
List.of
,Set.of
, undMap.of
, die genutzt werden sollte, statt. Sie sind schneller und effizienter als der double-brace-Initialisierung.InformationsquelleAutor Mikhail Kholodkov
Dies scheint die gleiche wie die mit dem Schlüsselwort so beliebt in flash und vbscript. Es ist eine Methode zu verändern, was
this
ist und nichts mehr.this
ist. Die syntax erzeugt nur eine anonyme Klasse (also jede Bezugnahme aufthis
würde sich auf das Objekt der neuen anonymen Klasse), und verwendet dann eine Initialisierung block{...}
um die Initialisierung des neu erzeugten Instanz.InformationsquelleAutor Chuck Vose