Sie gehen zu Recht davon aus, dass der für nicht statische innere Klassen verfügbare Attributzugriff zu einer hohen Kopplung und damit zu einer geringeren Codequalität führt und (nicht anonyme und nicht lokale ) innere Klassen im Allgemeinen statisch sein sollten.
Die Auswirkungen der Entscheidung, die innere Klasse nicht statisch zu machen, auf das Design sind in Java Puzzlers , Puzzle 90 (die fett gedruckte Schrift im folgenden Zitat stammt von mir) aufgeführt:
Wenn Sie eine Member-Klasse schreiben, fragen Sie sich, ob diese Klasse wirklich eine einschließende Instanz benötigt. Wenn die Antwort nein ist, machen Sie es static. Innere Klassen sind manchmal nützlich, aber sie können leicht zu Komplikationen führen, die das Verständnis eines Programms erschweren. Sie haben komplexe Wechselwirkungen mit Generika (Puzzle 89), Reflexion (Puzzle 80) und Vererbung (dieses Puzzle) . Wenn Sie dies angeben Inner1, verschwindet staticdas Problem. Wenn Sie dies auch erklären Inner2, können staticSie tatsächlich verstehen, was das Programm tut: ein netter Bonus in der Tat.
Zusammenfassend ist es selten angebracht, dass eine Klasse sowohl eine innere Klasse als auch eine Unterklasse einer anderen Klasse ist. Generell ist es selten angebracht, eine innere Klasse zu erweitern. Wenn Sie müssen, denken Sie lange und gründlich über die beiliegende Instanz nach. Ziehen Sie außerdem staticverschachtelte Klassen Nicht-Klassen vor static. Die meisten Mitgliederklassen können und sollten deklariert werden static.
Wenn Sie interessiert sind, finden Sie in dieser Antwort unter Stapelüberlauf eine detailliertere Analyse von Puzzle 90 .
Es ist erwähnenswert, dass es sich bei der obigen Beschreibung im Wesentlichen um eine erweiterte Version der Anleitung handelt, die im Lernprogramm für Java- Klassen und -Objekte enthalten ist :
Verwenden Sie eine nicht statische verschachtelte Klasse (oder innere Klasse), wenn Sie Zugriff auf die nicht öffentlichen Felder und Methoden einer einschließenden Instanz benötigen. Verwenden Sie eine statische verschachtelte Klasse, wenn Sie diesen Zugriff nicht benötigen.
Die Antwort auf die Frage, die Sie in anderen Worten pro Lernprogramm gestellt haben, ist der einzige überzeugende Grund für die Verwendung von nicht statisch, wenn der Zugriff auf die nicht öffentlichen Felder und Methoden einer einschließenden Instanz erforderlich ist .
Der Wortlaut des Tutorials ist ziemlich weit gefasst (dies könnte der Grund sein, warum Java-Puzzler versuchen, es zu stärken und einzugrenzen). Insbesondere der direkte Zugriff auf umschließende Instanzfelder war nach meiner Erfahrung nie wirklich erforderlich - in dem Sinne, dass alternative Methoden wie die Übergabe als Konstruktor- / Methodenparameter immer einfacher zu debuggen und zu warten waren.
Insgesamt machte meine (ziemlich schmerzhafte) Begegnung mit dem Debuggen innerer Klassen, die direkt auf Felder umschließender Instanzen zugreifen, den starken Eindruck, dass diese Praxis der Verwendung des globalen Staates und der damit verbundenen bekannten Übel ähnelt .
Natürlich macht Java es so, dass der Schaden einer solchen "quasi globalen" Klasse in der einschließenden Klasse enthalten ist, aber als ich eine bestimmte innere Klasse ausprüfen musste, fühlte es sich so an, als würde eine solche Pflasterung nicht dazu beitragen, die Schmerzen zu lindern "fremde" Semantik und Details im Auge zu behalten, anstatt sich ganz auf die Analyse eines bestimmten störenden Objekts zu konzentrieren.
Der Vollständigkeit halber kann es Fälle geben, in denen die obigen Überlegungen nicht zutreffen. Beispielsweise deutet diese Funktion beim Lesen von " map.keySet" -Javadocs auf eine enge Kopplung hin und macht daher Argumente gegen nicht statische Klassen ungültig:
Gibt eine SetAnsicht der in dieser Map enthaltenen Schlüssel zurück. Das Set wird von der Karte unterstützt, sodass Änderungen an der Karte in das Set übernommen werden und umgekehrt.
Nicht das obige würde es irgendwie einfacher machen, den beteiligten Code zu warten, zu testen und zu debuggen, aber es könnte einem zumindest erlauben zu argumentieren, dass die Komplikation mit der beabsichtigten Funktionalität übereinstimmt / gerechtfertigt ist.