Ich habe mir den Java-Code angesehen LinkedList
und festgestellt, dass er eine statisch verschachtelte Klasse verwendet Entry
.
public class LinkedList<E> ... {
...
private static class Entry<E> { ... }
}
Was ist der Grund für die Verwendung einer statisch verschachtelten Klasse anstelle einer normalen inneren Klasse?
Der einzige Grund, an den ich denken konnte, war, dass Entry keinen Zugriff auf Instanzvariablen hat und daher aus OOP-Sicht eine bessere Kapselung aufweist.
Aber ich dachte, es könnte andere Gründe geben, vielleicht Leistung. Was könnte es sein?
Hinweis. Ich hoffe, ich habe meine Begriffe richtig verstanden, ich hätte es eine statische innere Klasse genannt, aber ich denke, das ist falsch: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
Antworten:
Die Sun-Seite, auf die Sie verlinken, weist einige wesentliche Unterschiede auf:
Es ist nicht erforderlich
LinkedList.Entry
, eine Klasse der obersten Ebene zu sein, da diese nur von verwendet wirdLinkedList
(es gibt einige andere Schnittstellen, für die auch statische verschachtelte Klassen benannt sindEntry
, z. B.Map.Entry
- dasselbe Konzept). Und da es keinen Zugriff auf die Mitglieder von LinkedList benötigt, ist es sinnvoll, statisch zu sein - es ist ein viel saubererer Ansatz.Wie Jon Skeet betont, ist es meiner Meinung nach eine bessere Idee, wenn Sie eine verschachtelte Klasse verwenden, zunächst statisch zu sein und dann anhand Ihrer Verwendung zu entscheiden, ob sie wirklich nicht statisch sein muss.
quelle
#comment113712_253507
A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class
Wie ist das möglich, wenn nur ein Absatz vor den DokumentenStatic nested classes do not have access to other members of the enclosing class
A nested (non-static) class interacts with the instance members of its outer class (and other classes) just like any other top-level class
An inner class interacts with the instance members through an implicit reference to its enclosing class
und dass dies aus einer anderen interessanten Eigenschaftnon-static inner classes
sowieanonymous inner classes
oderlocal classes defined inside a block
: sie alle nicht haben können eineno-arg
Konstruktor Ursache der Compiler wird implizit die ARG - Sequenz eines jeden Konstruktor , um prepend eine Referenz einer Instanz des einschließe passieren Klasse. Ziemlich einfach.Meiner Meinung nach sollte die Frage umgekehrt sein, wenn Sie eine innere Klasse sehen - tut es wirklich eine innere Klasse sein, mit der zusätzlichen Komplexität und dem impliziten (und nicht expliziten und klareren IMO) Verweis auf eine Instanz der enthaltenden Klasse?
Wohlgemerkt, ich bin als C # -Fan voreingenommen - C # hat nicht das Äquivalent zu inneren Klassen, obwohl es verschachtelte Typen hat. Ich kann nicht sagen, dass ich den inneren Unterricht noch verpasst habe :)
quelle
Hier sind nicht offensichtliche Probleme mit der Speicheraufbewahrung zu berücksichtigen. Da eine nicht statische innere Klasse einen impliziten Verweis auf ihre 'äußere' Klasse beibehält, wird auch auf die äußere Instanz stark verwiesen, wenn auf eine Instanz der inneren Klasse stark verwiesen wird. Dies kann zu Kopfkratzern führen, wenn die äußere Klasse nicht durch Müll gesammelt wird, obwohl anscheinend nichts darauf verweist.
quelle
Zum einen haben nicht statische innere Klassen ein zusätzliches, verstecktes Feld, das auf die Instanz der äußeren Klasse verweist. Wenn die Entry-Klasse also nicht statisch wäre, hätte sie nicht nur Zugriff, den sie nicht benötigt, sondern auch vier statt drei Zeiger.
In der Regel würde ich sagen, wenn Sie eine Klasse definieren, die im Grunde genommen als Sammlung von Datenelementen fungiert, wie z. B. eine "Struktur" in C, sollten Sie in Betracht ziehen, sie statisch zu machen.
quelle
Statische innere Klasse wird im Builder-Muster verwendet. Die statische innere Klasse kann ihre äußere Klasse instanziieren, die nur einen privaten Konstruktor hat. Sie können also die statische innere Klasse verwenden, um die äußere Klasse zu instanziieren, die nur einen privaten Konstruktor hat. Sie können mit der inneren Klasse nicht dasselbe tun, da vor dem Zugriff auf die innere Klasse ein Objekt der äußeren Klasse erstellt werden muss.
Dies gibt x: 1 aus
quelle
Die statisch verschachtelte Klasse ist wie jede andere äußere Klasse, da sie keinen Zugriff auf Mitglieder der äußeren Klasse hat.
Nur zur Vereinfachung der Verpackung können wir statisch verschachtelte Klassen aus Gründen der Lesbarkeit in eine äußere Klasse einteilen. Abgesehen davon gibt es keinen anderen Anwendungsfall für statisch verschachtelte Klassen.
Ein Beispiel für eine solche Verwendung finden Sie in der Android R.java-Datei (Ressourcen). Der Res-Ordner von Android enthält Layouts (mit Bildschirmdesigns), einen Zeichenordner (mit für das Projekt verwendeten Bildern), einen Werteordner (mit Zeichenfolgenkonstanten) usw.
Da alle Ordner Teil des Res-Ordners sind, generiert das Android-Tool eine R.java-Datei (Ressourcen), die intern viele statisch verschachtelte Klassen für jeden ihrer inneren Ordner enthält.
Hier ist das Erscheinungsbild der in Android generierten R.java-Datei: Hier werden sie nur zur Vereinfachung der Verpackung verwendet.
quelle
Von http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html :
quelle
Einfaches Beispiel:
Wenn die Klasse nicht statisch ist, kann sie nur in einer Instanz der oberen Klasse instanziiert werden (also nicht in dem Beispiel, in dem main eine statische Funktion ist).
quelle
Einer der Gründe für statisch oder normal ist das Laden von Klassen. Sie können eine innere Klasse im Konstruktor ihres übergeordneten Elements nicht instanziieren.
PS: Ich habe immer verstanden, dass "verschachtelt" und "inner" austauschbar sind. Es mag subtile Nuancen in den Begriffen geben, aber die meisten Java-Entwickler würden es auch verstehen.
quelle
Nicht statische innere Klassen können zu Speicherlecks führen, während statische innere Klassen vor ihnen schützen. Wenn die äußere Klasse beträchtliche Daten enthält, kann dies die Leistung der Anwendung beeinträchtigen.
quelle
Ich weiß nichts über Leistungsunterschiede, aber wie Sie sagen, ist eine statisch verschachtelte Klasse nicht Teil einer Instanz der einschließenden Klasse. Es scheint nur einfacher zu sein, eine statisch verschachtelte Klasse zu erstellen, es sei denn, Sie benötigen sie wirklich als innere Klasse.
Es ist ein bisschen so, warum ich meine Variablen in Java immer endgültig mache - wenn sie nicht endgültig sind, weiß ich, dass mit ihnen etwas Lustiges los ist. Wenn Sie eine innere Klasse anstelle einer statisch verschachtelten Klasse verwenden, sollte es einen guten Grund geben.
quelle
Die Verwendung einer statischen verschachtelten Klasse anstelle einer nicht statischen Klasse kann in einigen Fällen Leerzeichen sparen. Zum Beispiel: Implementieren eines
Comparator
innerhalb einer Klasse, sagen wir Student.Dann
static
stellt das sicher, dass die Schülerklasse nur einen Komparator hat, anstatt jedes Mal, wenn eine neue Schülerinstanz erstellt wird, einen neuen zu instanziieren.quelle
Vorteil der inneren Klasse--
Ohne die Existenz der äußeren Klasse wird die innere Klasse nicht existieren.
Es gibt vier Arten von innerer Klasse.
Punkt ---
um die normale innere Klasse im statischen Bereich der äußeren Klasse aufzurufen.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
um die normale innere Klasse im Instanzbereich der äußeren Klasse aufzurufen.
Inner i=new Inner();
um eine normale innere Klasse außerhalb der äußeren Klasse aufzurufen.
Outer 0=new Outer(); Outer.Inner i= O.new Inner();
innerhalb der inneren Klasse Dieser Zeiger auf die innere Klasse.
this.member-current inner class outerclassname.this--outer class
Für die innere Klasse gilt der Modifikator - public, default,
final,abstract,strictfp,+private,protected,static
Outer $ Inner ist der Name des inneren Klassennamens.
innere Klasse innerhalb der Instanzmethode, dann können wir auf das statische Feld und das Instanzfeld der äußeren Klasse zugreifen.
10.inner Klasse innerhalb der statischen Methode, dann können wir nur auf das statische Feld von zugreifen
äußere Klasse.
quelle