Il punto è che le variabili di metodo-locale dal tipo di inclusione sono in realtà copiati alle istanze di classi anonime (questo è perché dei problemi relativi al frame di attivazione, ma non approfondirò i dettagli in quanto questo non è realmente pertinente alla domanda), motivo per cui devono essere definitivi, perché la variabile nell'istanza di tipo nidificata non è più la stessa.
Così, qui è il primo esempio:
void foo() {
int a = 3;
new Runnable() {
@Override
public void run() {
a += 3;
}
};
}
Questo non si compila, perché non si può fare riferimento a una variabile non finale in un metodo di classe anonima. Quando aggiungi un modificatore finale alla dichiarazione di a
, il valore di a
verrebbe copiato nell'istanza creata della classe anonima che hai definito. Tuttavia, non ti sarà consentito modificare il valore di a
, perché le modifiche non sarebbero visibili al metodo in cui è stato dichiarato a
.
Tuttavia, le classi anonime non sono statici, cioè, hanno un riferimento all'istanza che racchiude (a meno che il metodo in cui sono dichiarate è statico), che è possibile utilizzare per modificare le variabili di istanza allegando:
int a = 3;
void foo() {
new Runnable() {
@Override
public void run() {
a += 3;
}
};
}
Questo esempio viene compilato e aumenterà di a
di 3 ogni volta che viene chiamato il metodo run()
dell'istanza di classe anonima. (In questo esempio non viene mai chiamato, ma è solo un esempio.)
Quindi, per riassumere, è necessario convertire la variabile seatno
da una variabile di metodo locale a una variabile di istanza del tipo di inclusione.Oppure, se lo è ancora, è necessario rimuovere il modificatore finale poiché le variabili finali possono essere assegnate una sola volta.
Aggiornamento: In Java 8, viene introdotto il concetto di efficacemente finali variabili (vedi Java Language Specification). Tuttavia, nel primo esempio di questo post, la variabile a
viene assegnata più volte, il che impedisce che sia effettivamente definitiva. Ciò significa che questo esempio non viene ancora compilato con Java 8. (L'errore di compilazione è "La variabile locale definita in un ambito allegato deve essere definitiva o effettivamente definitiva")
la variabile 'seatno' contiene la parola chiave finale. –