127 Stimmen

Ist es möglich, anonyme innere Klassen in Java statisch zu machen?

In Java können verschachtelte Klassen entweder static oder nicht. Wenn sie es sind static enthalten sie keinen Verweis auf den Zeiger der enthaltenden Instanz (sie werden auch nicht mehr als innere Klassen bezeichnet, sondern als verschachtelte Klassen).

Vergessen, eine verschachtelte Klasse zu erstellen static wenn es diesen Verweis nicht benötigt, kann zu Problemen mit der Garbage Collection oder der Escape-Analyse führen.

Ist es möglich, eine anonyme innere Klasse zu erstellen static auch? Oder findet der Compiler dies automatisch heraus (was er könnte, da es keine Unterklassen geben kann)?

Wenn ich zum Beispiel einen anonymen Komparator erstelle, brauche ich den Verweis nach außen fast nie:

  Collections.sort(list, new Comparator<String>(){
       int compare(String a, String b){
          return a.toUpperCase().compareTo(b.toUpperCase());
       }
  }

139voto

Michael Myers Punkte 183216

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 zu ändern static verschachtelte Klassen, wenn sie nicht ihre impliziten this Hinweis.

Editar: Tom Hawtin - tackline sagt, dass, wenn die anonyme Klasse in einem statischen Kontext erstellt wird (z. B. in der main Methode), ist die anonyme Klasse in der Tat static . Aber die JLS stimmt nicht zu :

Eine anonyme Klasse ist niemals abstract (§8.1.1.1). Eine anonyme Klasse ist immer eine innere Klasse (§8.1.3); sie ist niemals static (§8.1.1, §8.5.1). Eine anonyme Klasse ist immer implizit final (§8.1.1.2).

Roedy Green's Java-Glossar sagt, dass die Tatsache, dass anonyme Klassen in einem statischen Kontext zulässig sind, ist implementierungsabhängig:

Wenn Sie diejenigen, die Ihren Code pflegen, verblüffen wollen, dann haben einige Leute Folgendes entdeckt javac.exe erlaubt anonyme Klassen innerhalb von static Init-Code und static Methoden, auch wenn die Sprachspezifikation besagt, dass anonyme Klassen niemals static . Diese anonymen Klassen haben natürlich keinen Zugriff auf die Instanzfelder des Objekts. Ich empfehle, dies nicht zu tun. Die Funktion jederzeit gezogen werden können.

Bearbeiten 2: Die JLS behandelt statische Kontexte expliziter in §15.9.2 :

Lassen Sie C die zu instanziierende Klasse sein, und i die zu erstellende Instanz sein. Wenn C eine innere Klasse ist, dann i kann eine unmittelbar umschließende Instanz haben. Die unmittelbar umschließende Instanz von i (§8.1.3) wird wie folgt bestimmt.

  • Wenn C ist also eine anonyme Klasse:
    • Wenn der Ausdruck zur Erzeugung der Klasseninstanz in einem statischen Kontext (§8.1.3) auftritt, dann i hat keine unmittelbar umschließende Instanz.
    • Andernfalls wird die unmittelbar umschließende Instanz von i est this .

Eine anonyme Klasse in einem statischen Kontext ist also ungefähr gleichbedeutend mit einer static verschachtelte Klasse, da sie keinen Verweis auf die umschließende Klasse enthält, obwohl sie technisch gesehen keine Klasse ist. static Klasse.

16voto

Neil Coffey Punkte 21238

Ich glaube, es gibt hier eine gewisse Verwirrung in der Nomenklatur, die zugegebenermaßen zu albern und verwirrend ist.

Wie auch immer Sie sie nennen, diese Muster (und einige Varianten mit unterschiedlicher Sichtbarkeit) sind alle möglichen, normalen, legalen Java:

public class MyClass {
  class MyClassInside {
  }
}

public class MyClass {
  public static class MyClassInside {
  }
}

public class MyClass {
  public void method() {
    JComponent jc = new JComponent() {
      ...
    }
  }
}

public class MyClass {
  public static void myStaticMethod() {
    JComponent jc = new JComponent() {
      ...
    }
  }
}

Sie sind in der Sprachspezifikation vorgesehen (wenn Sie sich wirklich daran stören, sehen Sie in Abschnitt 15.9.5.1 nach, wo die statische Methode enthalten ist).

Aber dieses Zitat ist schlichtweg falsch :

javac.exe erlaubt anonyme Klassen innerhalb von statischem Init-Code und statischen Methoden, auch wenn die Sprachspezifikation sagt, dass anonyme Klassen niemals statisch sind

Ich glaube, der zitierte Autor verwechselt die Statik Stichwort mit statischer Kontext . (Zugegeben, die JLS ist in dieser Hinsicht auch etwas verwirrend.)

Ehrlich gesagt sind alle oben genannten Muster in Ordnung (egal wie man sie nennt, "verschachtelt", "inner", "anonym", was auch immer...). Wirklich, niemand wird diese Funktionalität in der nächsten Version von Java plötzlich entfernen. Ehrlich gesagt!

15voto

Tom Hawtin - tackline Punkte 142461

Irgendwie. Eine anonyme innere Klasse, die in einer statischen Methode erstellt wird, ist natürlich effektiv statisch, da es keine Quelle für ein äußeres this gibt.

Es gibt einige technische Unterschiede zwischen inneren Klassen in statischen Kontexten und statischen verschachtelten Klassen. Wenn Sie daran interessiert sind, lesen Sie die JLS 3rd Ed.

6voto

Andrew Duffy Punkte 6500

Innere Klassen können nicht statisch sein - eine statische verschachtelte Klasse ist keine innere Klasse. Das Java-Tutorial spricht hier darüber .

0voto

Luca Punkte 1512

Anonyme innere Klassen sind niemals statisch (sie können keine statischen Methoden oder nicht-finale statische Felder deklarieren), aber wenn sie in einem statischen Kontext (statische Methode oder statisches Feld) definiert sind, verhalten sie sich wie statisch in dem Sinne, dass sie nicht auf nicht-statische (d.h. Instanz-) Mitglieder der umschließenden Klasse zugreifen können (wie alles andere in einem statischen Kontext)

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