Beispiel:
public class TestClass {
public static void main(String[] args) {
TestClass t = new TestClass();
}
private static void testMethod() {
abstract class TestMethod {
int a;
int b;
int c;
abstract void implementMe();
}
class DummyClass extends TestMethod {
void implementMe() {}
}
DummyClass dummy = new DummyClass();
}
}
Ich fand heraus, dass der obige Code in Java vollkommen legal ist. Ich habe folgende Fragen.
- Was nützt es, jemals eine Klassendefinition in einer Methode zu haben?
- Wird eine Klassendatei für generiert?
DummyClass
- Es fällt mir schwer, mir dieses Konzept objektorientiert vorzustellen. Eine Klassendefinition in einem Verhalten haben. Wahrscheinlich kann mir jemand mit gleichwertigen Beispielen aus der realen Welt erzählen.
- Abstrakte Klassen innerhalb einer Methode klingen für mich ein bisschen verrückt. Aber keine Schnittstellen erlaubt. Gibt es einen Grund dafür?
java
class
local-class
Prahler
quelle
quelle
Antworten:
Dies wird als lokale Klasse bezeichnet.
2 ist ganz einfach: Ja, es wird eine Klassendatei generiert.
1 und 3 sind die gleiche Frage. Sie würden eine lokale Klasse verwenden, in der Sie niemals eine instanziieren müssen oder die Implementierungsdetails nur in einer Methode kennen.
Eine typische Verwendung wäre das Erstellen einer Wegwerfimplementierung einer Schnittstelle. Zum Beispiel sehen Sie oft so etwas:
Wenn Sie eine Reihe davon erstellen und etwas damit tun müssen, können Sie dies in ändern
In Bezug auf Schnittstellen: Ich bin nicht sicher, ob es ein technisches Problem gibt, das lokal definierte Schnittstellen zu einem Problem für den Compiler macht, aber selbst wenn dies nicht der Fall ist, würden sie keinen Mehrwert bringen. Wenn eine lokale Klasse, die eine lokale Schnittstelle implementiert, außerhalb der Methode verwendet würde, wäre die Schnittstelle bedeutungslos. Und wenn eine lokale Klasse nur innerhalb der Methode verwendet werden würde, würden sowohl die Schnittstelle als auch die Klasse innerhalb dieser Methode implementiert, sodass die Schnittstellendefinition redundant wäre.
quelle
parameter
Dies kann in der einschließenden Methode deklariert werden und ist für beide Threads zugänglich.Diese werden lokale Klassen genannt . Eine ausführliche Erklärung und ein Beispiel finden Sie hier . Das Beispiel gibt eine bestimmte Implementierung zurück, über die wir außerhalb der Methode nichts wissen müssen.
quelle
Die Klasse kann von außerhalb der Methode nicht gesehen werden (dh instanziiert, auf ihre Methoden wird ohne Reflexion zugegriffen). Es kann auch auf die in testMethod () definierten lokalen Variablen zugreifen, jedoch vor der Klassendefinition.
Ich dachte tatsächlich: "Es wird keine solche Datei geschrieben." bis ich es gerade ausprobiert habe: Oh ja, eine solche Datei wird erstellt! Es wird so etwas wie A $ 1B.class genannt, wobei A die äußere Klasse und B die lokale Klasse ist.
Insbesondere für Rückruffunktionen (Ereignishandler in GUIs wie onClick (), wenn auf eine Schaltfläche geklickt wird usw.) wird häufig "anonyme Klassen" verwendet - vor allem, weil Sie möglicherweise viele davon haben. Aber manchmal sind anonyme Klassen nicht gut genug - insbesondere können Sie keinen Konstruktor für sie definieren. In diesen Fällen können diese Methodenklassen eine gute Alternative sein.
quelle
TestClass$1TestMethodClass.class
analog zur.class
Benennung innerer Klassendateien erstellt .Der eigentliche Zweck ist es, uns zu ermöglichen, Klassen in Funktionsaufrufen inline zu erstellen, um diejenigen von uns zu trösten, die gerne so tun, als würden wir in einer funktionalen Sprache schreiben;)
quelle
Der einzige Fall, in dem Sie eine voll funktionsfähige innere Klasse gegenüber einer anonymen Klasse (auch bekannt als Java-Schließung) wünschen, ist, wenn die folgenden Bedingungen erfüllt sind
ZB will jemand eine
Runnable
und Sie möchten aufzeichnen, wann die Ausführung begonnen und beendet hat.Mit anonymer Klasse ist das nicht möglich, mit innerer Klasse ist das möglich.
Hier ist ein Beispiel, das meinen Standpunkt demonstriert
Bevor Sie dieses Muster verwenden, prüfen Sie bitte, ob einfache alte Klassen der obersten Ebene, innere Klassen oder statische innere Klassen bessere Alternativen sind.
quelle
Der Hauptgrund für die Definition innerer Klassen (innerhalb einer Methode oder einer Klasse) besteht darin, die Zugänglichkeit von Mitgliedern und Variablen der einschließenden Klasse und Methode zu behandeln. Eine innere Klasse kann private Datenelemente nachschlagen und sie bearbeiten. Wenn innerhalb einer Methode, kann es auch mit der endgültigen lokalen Variablen umgehen.
Innere Klassen helfen dabei, sicherzustellen, dass diese Klasse für die Außenwelt nicht zugänglich ist. Dies gilt insbesondere für Fälle der UI-Programmierung in GWT oder GXT usw., in denen JS-Generierungscode in Java geschrieben ist und das Verhalten für jede Schaltfläche oder jedes Ereignis durch Erstellen anonymer Klassen definiert werden muss
quelle
Ich bin im Frühjahr auf ein gutes Beispiel gestoßen. Das Framework verwendet das Konzept lokaler Klassendefinitionen innerhalb der Methode, um verschiedene Datenbankoperationen auf einheitliche Weise zu behandeln.
Angenommen, Sie haben einen Code wie diesen:
Schauen wir uns zunächst die Implementierung von execute () an:
Bitte beachten Sie die letzte Zeile. Spring macht genau diesen "Trick" auch für den Rest der Methoden:
Der "Trick" mit lokalen Klassen ermöglicht es dem Framework, alle diese Szenarien in einer einzigen Methode zu behandeln, die diese Klassen über die StatementCallback-Schnittstelle akzeptiert. Diese einzelne Methode fungiert als Brücke zwischen Aktionen (Ausführen, Aktualisieren) und allgemeinen Vorgängen (z. B. Ausführung, Verbindungsverwaltung, Fehlerübersetzung und Ausgabe der DBMS-Konsole).
quelle