Ist es möglich, Parameter zu übergeben oder auf externe Parameter an eine anonyme Klasse zuzugreifen? Beispielsweise:
int myVariable = 1;
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// How would one access myVariable here?
}
});
Gibt es eine Möglichkeit für den Listener, auf myVariable zuzugreifen oder myVariable zu übergeben, ohne den Listener als tatsächlich benannte Klasse zu erstellen?
java
anonymous-class
Lewis
quelle
quelle
final
lokale Variablen aus der einschließenden Methode referenzieren .this
.Antworten:
Technisch gesehen nein, da anonyme Klassen keine Konstruktoren haben können.
Klassen können jedoch auf Variablen verweisen, die Bereiche enthalten. Bei einer anonymen Klasse können dies Instanzvariablen aus den enthaltenden Klassen oder lokale Variablen sein, die als endgültig markiert sind.
edit : Wie Peter betonte, können Sie Parameter auch an den Konstruktor der Oberklasse der anonymen Klasse übergeben.
quelle
new ArrayList(10) { }
super()
und vor dem Rest des eigentlichen Konstruktors.new someclass(){ fields; {initializer} fields; methods(){} }
. Es ist wie ein statischer Initialisierer, jedoch ohne das statische Schlüsselwort. docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.6Ja, indem Sie eine Initialisierungsmethode hinzufügen, die 'this' zurückgibt, und diese Methode sofort aufrufen:
Keine "endgültige" Erklärung erforderlich.
quelle
final
Referenzobjekt zu erstellen, nur damit ich Informationen in meine anonymen Klassen bekommen kann. Ich danke Ihnen für das Teilen!init()
Funktion zurückkehrenthis
? Ich verstehe die Syntax nicht wirklich.Ja. Sie können Variablen erfassen, die für die innere Klasse sichtbar sind. Die einzige Einschränkung ist, dass es endgültig sein muss
quelle
this
die final ist.final
? Ich kann keine Alternative finden. Dies kann den Ursprungsparameter beeinflussen, für den er ausgelegt istfinal
.So was:
quelle
Dies wird die Magie tun
quelle
Wie unter http://www.coderanch.com/t/567294/java/java/declare-constructor-anonymous-class gezeigt , können Sie einen Instanzinitialisierer hinzufügen. Es ist ein Block, der keinen Namen hat und zuerst ausgeführt wird (genau wie ein Konstruktor).
Sieht so aus, als würden sie auch unter Warum Java-Instanz-Initialisierer besprochen ? und Wie unterscheidet sich ein Instanzinitialisierer von einem Konstruktor? diskutiert Unterschiede zu Konstruktoren.
quelle
final
Variablen verwendet werden, wie von aav beschrieben, aber diese Informationen wurden in dieser Antwort nicht bereitgestellt. Die mit Abstand beste Antwort ist die von Adam Mlodzinksi (ich verwende jetzt ausschließlich dieses Muster, keine Endrunde mehr!). Ich stehe zu meinem Kommentar, dass dies die gestellte Frage nicht beantwortet.Meine Lösung besteht darin, eine Methode zu verwenden, die die implementierte anonyme Klasse zurückgibt. Regelmäßige Argumente können an die Methode übergeben werden und sind in der anonymen Klasse verfügbar.
Zum Beispiel: (von einem GWT-Code zur Behandlung einer Textfeldänderung):
In diesem Beispiel wird auf die neue anonyme Klassenmethode verwiesen mit:
ODER unter Verwendung der Anforderungen des OP:
quelle
Andere Personen haben bereits geantwortet, dass anonyme Klassen nur auf endgültige Variablen zugreifen können. Sie lassen jedoch die Frage offen, wie die ursprüngliche Variable nicht endgültig bleiben soll. Adam Mlodzinski gab eine Lösung, ist aber ziemlich aufgebläht. Es gibt eine viel einfachere Lösung für das Problem:
Wenn Sie nicht
myVariable
endgültig sein möchten , müssen Sie es in einen neuen Bereich einschließen, in dem es keine Rolle spielt, ob es endgültig ist.Adam Mlodzinski tut in seiner Antwort nichts anderes als viel mehr Code.
quelle
init
Methode. Ich kann meinem Beispiel eine zusätzliche Codezeile hinzufügen, um diese zusätzliche Variable zu erhalten. Wenn Sie ein großer Fan von Builder-Mustern sind, können Sie sie gerne verwenden, aber in diesem Fall sind sie nicht erforderlich.final
variablen Lösung unterscheidet.Sie können einfache Lambdas verwenden ("Lambda-Ausdrücke können Variablen erfassen")
oder sogar eine Funktion
Die Verwendung von Function ist eine großartige Möglichkeit, Dekorateure und Adapter umzugestalten. siehe hier)
Ich habe gerade angefangen, etwas über Lambdas zu lernen. Wenn Sie also einen Fehler entdecken, können Sie gerne einen Kommentar schreiben.
quelle
Eine einfache Möglichkeit, einer externen Variablen einen Wert zu geben (gehört nicht zur Anonymus-Klasse), ist wie folgt!
Auf die gleiche Weise können Sie eine Methode erstellen, die das zurückgibt, was Sie möchten, wenn Sie den Wert einer externen Variablen erhalten möchten!
quelle
Ich dachte, anonyme Klassen wären im Grunde genommen wie Lambdas, aber mit schlechterer Syntax ... dies stellt sich als wahr heraus, aber die Syntax ist noch schlechter und führt dazu, dass (was sollte) lokale Variablen in die enthaltende Klasse ausbluten.
Sie können auf keine endgültigen Variablen zugreifen, indem Sie sie in Felder der übergeordneten Klasse umwandeln.
Z.B
Schnittstelle:
Klasse:
Ich weiß nicht, ob sie das in Java 8 geklärt haben (ich stecke in der EE-Welt fest und habe noch keine 8), aber in C # würde es so aussehen:
Sie brauchen auch keine separate Schnittstelle in c # ... Ich vermisse es! Ich finde mich dabei, schlechtere Designs in Java zu erstellen und mich mehr zu wiederholen, weil die Menge an Code + Komplexität, die Sie in Java hinzufügen müssen, um etwas wiederzuverwenden, schlimmer ist, als viel zu kopieren und einzufügen.
quelle