Wenn Sie dekompilieren eine innere Klasse (oder schauen Sie es Debugger) können Sie sehen, dass es generierter Code für den Zugriff auf die Instanz der äußeren Klasse, mit der sie erstellt wurde. Der Overhead dafür ist mehr Speicher für den zusätzlichen Zeiger, mehr CPU für die Garbage-Collection wegen des zusätzlichen Pointers zum Testen, und wenn Sie nichts auswählen wollen, längere Kompilierzeit. Das Erstellen von Instanzen von nicht statischen inneren Klassen ist etwas komplizierter, da Sie eine Instanz der äußeren Klasse benötigen, um sie zu erstellen.
Die Sichtbarkeit von statischen und nicht statischen inneren Klassen kann gesteuert werden. Normalerweise sind sie privat, wenn ihre Implementierung stark mit internen Details der äußeren Klasse verbunden ist, und der Entwickler glaubt nicht, dass der Code wiederverwendet werden kann. In diesem Sinne sind sie nicht besser als private Funktionen. Innere Klassen können in Fällen wie Map.Entry öffentlich sein, wo die innere Klasse stark mit der von der Klasse offengelegten Schnittstelle verbunden ist, und der Entwickler denkt nicht, dass Map.Entry ohne irgendeine Art von Map verwendet werden kann. Beide Typen haben Zugriff auf private Mitglieder der äußeren Klasse und die äußere Klasse hat Zugriff auf private Mitglieder der inneren Klasse.
Instanzen von statischen und nicht statischen inneren Klassen werden wie jede andere Klasse gesammelt.Es gibt keine spezielle Verbindung zwischen der Grabage-Sammlung der äußeren Klasse und der Garbage Collection der inneren Klasse.
Im Fall von Implementierungen der UI-Klassen wie swing oder android sehen Sie statische innere Klassen, weil sie wie private Funktionen behandelt werden. Diese Klassen sind nicht für die Wiederverwendbarkeit außerhalb der äußeren Klasse entwickelt und sind stark mit der internen Implementierung der äußeren Klasse verbunden. Es gibt keinen Grund, sie zu entlarven und sicherzustellen, dass sie in mehr Fällen als dem spezifischen Kontext der äußeren Klassenanforderungen arbeiten können.
Das stimmt, aber es gibt noch mehr - manchmal haben Sie keinen Bezug zur äußeren Klasse und wollen immer noch das Innere instanziieren (wenn es sichtbar ist). – ognian
+1 für den Eindruck, was der Compiler aus der Eingabequelle macht – Seven
Kann nicht eine nicht-statische innere Klasse explizit einen Verweis auf den äußeren deklarieren (muss nur manuell instantiiert werden) und gibt somit das Beste aus beiden Welten: die äußere Referenz ohne statische Speicherkosten? Ist eine statische innere Klasse nicht reentrant, weshalb sie nur dann nützlich ist, wenn eine einzelne Instanz benötigt wird? – samosaris