Riferendosi ai campi non finali di classe contenitrice all'interno di una classe interna anonima in Java
-
20-09-2019 - |
Domanda
In Java, lo so che è possibile fare qualcosa di simile a questo:
public class Greeter {
public void greetEventually() {
final String greeting = "Hello!";
Job j = new Job() {
public void run() {
System.out.println(greeting);
}
};
j.schedule();
}
}
Ciò eseguire il Job
anonima ad un certo punto in futuro. Questo funziona perché le classi anonime sono autorizzati a fare riferimento alle variabili finali nel perimetro che racchiude.
Quello che non sono sicuro circa è il caso seguente:
public class Greeter {
private String greeting;
// ... Other methods that might mutate greeting ...
public void greetEventually() {
Job j = new Job() {
public void run() {
System.out.println(greeting);
}
};
j.schedule();
}
}
In questo caso il mio Job
anonima si riferisce ad un campo non finale della classe contenitrice. Quando viene eseguito il lavoro, io vedo il valore del campo greeting
come lo era quando il lavoro è stato creato, o come è quando è in esecuzione? Penso di sapere la risposta, ma ho pensato che fosse una domanda interessante, e in un primo momento io e un paio di colleghi stessi ripensamenti per qualche minuto. Lasciai
Soluzione
Vedrai il valore di greeting
come lo è quando il Job
anonima esegue.
Il modificatore final
è richiesto solo per le variabili locali, non variabili membro.
Altri suggerimenti
Si accede attraverso il campo (l'esterno) this
). Si può pensare di this
nel modo più efficace una variabile locale final
. il locale è unico final
, l'oggetto puntato non è (necessariamente) costante. Immaginate una variabile locale con lo stesso valore this
e dovrebbe essere chiaro.
public class Greeter {
private String greeting;
// ... Other methods that might mutate greeting ...
public void greetEventually() {
private final Greeter greeter = this; // <---
Job j = new Job() {
public void run() {
System.out.println( greeter.greeting ); // <---
}
};
j.schedule();
}
}
Il modificatore finale si applica alle variabili locali solo per fornire variabili per ogni istanza della classe interna, in modo da usare: def saluto String;
Quando avete bisogno di una sola istanza della variabile (come il caso di costanti o risorse comuni), l'uso: String greeting privato;