In Java können verschachtelte Klassen entweder sein static
oder nicht. Wenn static
dies der Fall ist , enthalten sie keinen Verweis auf den Zeiger der enthaltenen Instanz (sie werden auch nicht mehr als innere Klassen bezeichnet, sondern als verschachtelte Klassen).
Das Vergessen, eine verschachtelte Klasse zu erstellen, static
wenn diese Referenz nicht benötigt wird, kann zu Problemen bei der Speicherbereinigung oder der Escape-Analyse führen.
Ist es möglich, auch eine anonyme innere Klasse static
zu bilden? Oder findet der Compiler dies automatisch heraus (was er könnte, weil es keine Unterklassen geben kann)?
Wenn ich zum Beispiel einen anonymen Komparator mache, brauche ich fast nie den Verweis nach außen:
Collections.sort(list, new Comparator<String>(){
int compare(String a, String b){
return a.toUpperCase().compareTo(b.toUpperCase());
}
}
java
syntax
inner-classes
Thilo
quelle
quelle
Collections.sort(list, String.CASE_INSENSITIVE_ORDER)
seit Java 2 funktioniert, gelesen, da die Sammlungs-API existiert…Antworten:
Nein, das können Sie nicht, und nein, der Compiler kann es nicht herausfinden. Aus diesem Grund schlägt FindBugs immer vor, anonyme innere Klassen in benannte
static
verschachtelte Klassen zu ändern, wenn sie ihre implizitethis
Referenz nicht verwenden .Bearbeiten: Tom Hawtin - Tackline sagt, dass, wenn die anonyme Klasse in einem statischen Kontext (z. B. in der
main
Methode) erstellt wird, die anonyme Klasse tatsächlich iststatic
. Aber die JLS ist anderer Meinung :Das Java-Glossar von Roedy Green besagt, dass die Tatsache, dass anonyme Klassen in einem statischen Kontext zulässig sind, implementierungsabhängig ist:
Edit 2: Das JLS behandelt statische Kontexte in §15.9.2 expliziter :
Eine anonyme Klasse in einem statischen Kontext entspricht also in etwa einer
static
verschachtelten Klasse, da sie keinen Verweis auf die einschließende Klasse enthält, obwohl es sich technisch gesehen nicht um einestatic
Klasse handelt.quelle
true
mit javac (sun-jdk-1.7.0_10) undfalse
mit Eclipse - Compiler.So'ne Art. Eine anonyme innere Klasse, die in einer statischen Methode erstellt wurde, ist offensichtlich effektiv statisch, da es keine Quelle für eine äußere Klasse gibt.
Es gibt einige technische Unterschiede zwischen inneren Klassen in statischen Kontexten und statisch verschachtelten Klassen. Wenn Sie interessiert sind, lesen Sie die JLS 3rd Ed.
quelle
Ich denke, die Nomenklatur hier ist etwas verwirrend, was zugegebenermaßen zu albern und verwirrend ist.
Wie auch immer Sie sie nennen, diese Muster (und einige Variationen mit unterschiedlicher Sichtbarkeit) sind alle möglich, normales, legales Java:
Sie werden in der Sprachspezifikation berücksichtigt (wenn Sie wirklich gestört sind, finden Sie in Abschnitt 15.9.5.1 die Informationen zur statischen Methode).
Aber dieses Zitat ist einfach falsch :
Ich denke, der zitierte Autor verwechselt das statische Schlüsselwort mit dem statischen Kontext . (Zugegeben, das JLS ist auch in dieser Hinsicht etwas verwirrend.)
Ehrlich gesagt sind alle oben genannten Muster in Ordnung (wie auch immer Sie sie "verschachtelt", "inner", "anonym" nennen, was auch immer ...). Wirklich, niemand wird diese Funktionalität in der nächsten Version von Java plötzlich entfernen. Ehrlich!
quelle
new
undJComponent
in Ihrem dritten Beispiel eine "statische" hinzu .Innere Klassen können nicht statisch sein - eine statisch verschachtelte Klasse ist keine innere Klasse. Das Java-Tutorial spricht hier darüber .
quelle
anonyme innere Klassen sind niemals statisch (sie können keine statischen Methoden oder nicht endgültigen statischen Felder deklarieren), aber wenn sie in einem statischen Kontext (statische Methode oder statisches Feld) definiert sind, verhalten sie sich in dem Sinne statisch, dass sie es nicht können Zugriff auf nicht statische (dh Instanz-) Mitglieder der einschließenden Klasse (wie alles andere aus einem statischen Kontext)
quelle
Um eine anonyme innere Klasse statisch zu machen, indem Sie sie innerhalb einer statischen Methode aufrufen.
Dadurch wird die Referenz nicht entfernt. Sie können dies testen, indem Sie versuchen, die anonyme Klasse zu serialisieren und die einschließende Klasse nicht serialisierbar zu machen.
quelle