Was ist die Verwendung von anonymen Klassen in Java? Können wir sagen, dass die Verwendung einer anonymen Klasse einer der Vorteile von Java ist?
309
Was ist die Verwendung von anonymen Klassen in Java? Können wir sagen, dass die Verwendung einer anonymen Klasse einer der Vorteile von Java ist?
Antworten:
Mit einer "anonymen Klasse" meine ich anonyme innere Klasse .
Eine anonyme innere Klasse kann nützlich sein, wenn Sie eine Instanz eines Objekts mit bestimmten "Extras" wie z. B. überschreibenden Methoden erstellen, ohne eine Klasse tatsächlich unterordnen zu müssen.
Ich neige dazu, es als Verknüpfung zum Anhängen eines Ereignis-Listeners zu verwenden:
Die Verwendung dieser Methode beschleunigt das Codieren etwas, da ich keine zusätzliche Klasse erstellen muss, die implementiert wird
ActionListener
Ich kann nur eine anonyme innere Klasse instanziieren, ohne tatsächlich eine separate Klasse zu erstellen.Ich benutze diese Technik nur für "schnelle und schmutzige" Aufgaben, bei denen es sich unnötig anfühlt, eine ganze Klasse zu bilden. Mehrere anonyme innere Klassen, die genau dasselbe tun, sollten in eine tatsächliche Klasse umgestaltet werden, sei es eine innere Klasse oder eine separate Klasse.
quelle
overloading methods
und nichtoverriding methods
?Anonyme innere Klassen sind effektiv Schließungen, sodass sie zum Emulieren von Lambda-Ausdrücken oder "Delegaten" verwendet werden können. Nehmen Sie zum Beispiel diese Schnittstelle:
Sie können dies anonym verwenden, um eine erstklassige Funktion in Java zu erstellen . Angenommen, Sie haben die folgende Methode, die die erste Zahl zurückgibt, die größer als i in der angegebenen Liste ist, oder i, wenn keine Zahl größer ist:
Und dann haben Sie eine andere Methode, die die erste Zahl zurückgibt, die kleiner als i in der angegebenen Liste ist, oder i, wenn keine Zahl kleiner ist:
Diese Methoden sind nahezu identisch. Mit dem erstklassigen Funktionstyp F können wir diese wie folgt in eine Methode umschreiben:
Sie können eine anonyme Klasse verwenden, um die firstMatch-Methode zu verwenden:
Dies ist ein wirklich erfundenes Beispiel, aber es ist leicht zu erkennen, dass es eine ziemlich nützliche Funktion ist, Funktionen so weitergeben zu können, als wären sie Werte. Siehe "Kann Ihre Programmiersprache dies tun" von Joel selbst.
Eine schöne Bibliothek zum Programmieren von Java in diesem Stil: Functional Java.
quelle
Die anonyme innere Klasse wird in folgendem Szenario verwendet:
1.) Zum Überschreiben (Unterklassifizierung): Wenn die Klassendefinition nur im aktuellen Fall verwendet werden kann:
2.) Zum Implementieren einer Schnittstelle Wenn die Implementierung der Schnittstelle nur für den aktuellen Fall erforderlich ist:
3.) Argument definiert Anonyme innere Klasse:
quelle
Ich benutze sie manchmal als Syntax-Hack für die Map-Instanziierung:
vs.
Dies spart Redundanz, wenn viele put-Anweisungen ausgeführt werden. Ich habe jedoch auch Probleme damit, wenn die äußere Klasse per Remoting serialisiert werden muss.
quelle
Sie werden häufig als ausführliche Form des Rückrufs verwendet.
Ich nehme an, Sie könnten sagen, dass sie ein Vorteil sind, wenn Sie sie nicht haben und jedes Mal eine benannte Klasse erstellen müssen, aber ähnliche Konzepte werden in anderen Sprachen (als Abschlüsse oder Blöcke) viel besser implementiert.
Hier ist ein Swing-Beispiel
Obwohl es immer noch chaotisch ausführlich ist, ist es viel besser, als Sie zu zwingen, eine benannte Klasse für jeden wegwerfbaren Hörer wie diesen zu definieren (obwohl dies je nach Situation und Wiederverwendung immer noch der bessere Ansatz sein kann).
quelle
myButton.addActionListener(e -> { /* do stuff here */})
odermyButton.addActionListener(stuff)
wäre terser.Sie verwenden es in Situationen, in denen Sie eine Klasse für einen bestimmten Zweck in einer anderen Funktion erstellen müssen, z. B. als Listener, als ausführbare Datei (um einen Thread zu erzeugen) usw.
Die Idee ist, dass Sie sie aus dem Code einer Funktion heraus aufrufen, sodass Sie sie nie an anderer Stelle referenzieren, sodass Sie sie nicht benennen müssen. Der Compiler zählt sie nur auf.
Sie sind im Wesentlichen syntaktischer Zucker und sollten im Allgemeinen an einen anderen Ort gebracht werden, wenn sie größer werden.
Ich bin mir nicht sicher, ob dies einer der Vorteile von Java ist. Wenn Sie sie jedoch verwenden (und wir alle verwenden sie leider häufig), können Sie argumentieren, dass es sich um einen handelt.
quelle
Richtlinien für anonyme Klassen.
Die anonyme Klasse wird gleichzeitig deklariert und initialisiert.
Die anonyme Klasse muss auf eine und nur eine Klasse bzw. Schnittstelle erweitert oder implementiert werden.
Da die anonymouse-Klasse keinen Namen hat, kann sie nur einmal verwendet werden.
z.B:
quelle
ref.getClass().newInstance()
.Ja, anonyme innere Klassen sind definitiv einer der Vorteile von Java.
Mit einer anonymen inneren Klasse haben Sie Zugriff auf endgültige und Mitgliedsvariablen der umgebenden Klasse, was für Hörer usw. nützlich ist.
Ein großer Vorteil ist jedoch, dass der innere Klassencode, der eng mit der umgebenden Klasse / Methode / dem umgebenden Block verbunden ist (zumindest sein sollte), einen bestimmten Kontext hat (die umgebende Klasse, Methode und den umgebenden Block).
quelle
Dies ist auch eines der Beispiele für anonyme innere Typen, die Thread verwenden
quelle
Ich benutze anonyme Objekte zum Aufrufen neuer Threads.
quelle
Eine innere Klasse ist einer Instanz der äußeren Klasse zugeordnet, und es gibt zwei spezielle Arten: Lokale Klasse und Anonyme Klasse . Eine anonyme Klasse ermöglicht es uns, eine Klasse gleichzeitig zu deklarieren und zu instanziieren, wodurch der Code präzise wird. Wir verwenden sie, wenn wir eine lokale Klasse nur einmal benötigen, da sie keinen Namen haben.
Betrachten Sie das Beispiel aus doc, in dem wir eine
Person
Klasse haben:und wir haben eine Methode zum Drucken von Mitgliedern, die Suchkriterien entsprechen:
Wo
CheckPerson
ist eine Schnittstelle wie:Jetzt können wir eine anonyme Klasse verwenden, die diese Schnittstelle implementiert, um Suchkriterien wie folgt anzugeben:
Hier ist die Oberfläche sehr einfach und die Syntax der anonymen Klasse scheint unhandlich und unklar.
Java 8 hat einen Begriff Functional Interface eingeführt, der eine Schnittstelle mit nur einer abstrakten Methode ist, daher können wir sagen, dass
CheckPerson
es sich um eine funktionale Schnittstelle handelt. Wir können den Lambda-Ausdruck verwenden , mit dem wir die Funktion als Methodenargument übergeben können als:Wir können
Predicate
anstelle der Schnittstelle eine Standardfunktionsschnittstelle verwendenCheckPerson
, wodurch die erforderliche Codemenge weiter reduziert wird.quelle
Eine anonyme innere Klasse kann nützlich sein, wenn unterschiedliche Implementierungen für unterschiedliche Objekte angegeben werden. Sollte aber sehr sparsam verwendet werden, da dies zu Problemen bei der Programmlesbarkeit führt.
quelle
Eine der Hauptverwendungen anonymer Klassen bei der Klassenfinalisierung, die als Finalizer Guardian bezeichnet wird . In der Java-Welt sollte die Verwendung der Finalize-Methoden vermieden werden, bis Sie sie wirklich benötigen. Sie müssen sich daran erinnern, dass Sie beim Überschreiben der Finalisierungsmethode für Unterklassen immer auch aufrufen sollten
super.finalize()
, da die Finalisierungsmethode der Superklasse nicht automatisch aufgerufen wird und Sie Probleme mit Speicherverlusten haben können.In Anbetracht der oben genannten Tatsache können Sie einfach die anonymen Klassen wie folgt verwenden:
Mit dieser Technik haben Sie sich und Ihre anderen Entwickler entlastet,
super.finalize()
jede UnterklasseHeavyClass
der zu finalisierenden Methode aufzurufen .quelle
Sie können auf diese Weise eine anonyme Klasse verwenden
quelle
Hier scheint niemand erwähnt zu sein, aber Sie können auch eine anonyme Klasse verwenden, um generische Typargumente zu speichern (die normalerweise aufgrund von Typlöschung verloren gehen) :
Wenn Sie diese Klasse anonym instanziieren
dann so
holder
Instanz eine nicht gelöschte Definition des übergebenen Typs.Verwendung
Dies ist sehr praktisch, um Validatoren / Deserialisatoren zu erstellen. Sie können auch einen generischen Typ mit Reflexion instanziieren (wenn Sie also jemals einen
new T()
parametrisierten Typ verwenden wollten, sind Sie herzlich willkommen!) .Nachteile / Einschränkungen
quelle
Der beste Weg, um Code zu optimieren. Wir können auch eine überschreibende Methode einer Klasse oder Schnittstelle verwenden.
quelle
Eine anonyme innere Klasse wird verwendet, um ein Objekt zu erstellen, auf das nie wieder verwiesen wird. Es hat keinen Namen und wird in derselben Anweisung deklariert und erstellt. Dies wird verwendet, wenn Sie normalerweise die Variable eines Objekts verwenden würden. Sie ersetzen die Variable durch das
new
Schlüsselwort, einen Aufruf eines Konstruktors und die Klassendefinition in{
und}
.Wenn Sie ein Thread-Programm in Java schreiben, sieht es normalerweise so aus
Das
ThreadClass
hier verwendete wäre benutzerdefiniert. Diese Klasse implementiert dieRunnable
Schnittstelle, die zum Erstellen von Threads erforderlich ist. In demThreadClass
dasrun()
Verfahren (nur Verfahren inRunnable
) muss auch umgesetzt werden. Es ist klar, dass loswerdenThreadClass
effizienter wäre , und genau deshalb gibt es anonyme innere Klassen.Schauen Sie sich den folgenden Code an
Dieser Code ersetzt den Verweis
task
im obersten Beispiel. Anstatt eine separate Klasse zu haben, gibt die anonyme innere Klasse imThread()
Konstruktor ein unbenanntes Objekt zurück, das dieRunnable
Schnittstelle implementiert und dierun()
Methode überschreibt . Die Methoderun()
würde Anweisungen enthalten, die die vom Thread geforderte Arbeit erledigen.Bei der Beantwortung der Frage, ob anonyme innere Klassen einer der Vorteile von Java sind, muss ich sagen, dass ich nicht ganz sicher bin, da ich derzeit nicht mit vielen Programmiersprachen vertraut bin. Aber was ich sagen kann ist, dass es definitiv eine schnellere und einfachere Methode zum Codieren ist.
Referenzen: Sams bringt sich Java in der siebten Ausgabe von 21 Tagen bei
quelle
Ein weiterer Vorteil:
Wie Sie wissen, unterstützt Java keine Mehrfachvererbung. Wenn Sie also die Klasse "Thread" als anonyme Klasse verwenden, bleibt der Klasse noch ein Speicherplatz für jede andere Klasse zur Erweiterung übrig.
quelle