2011-01-24 11 views
9

Eventuali duplicati:
Cannot refer to a non-final variable inside an inner class defined in a different methodPerché le variabili locali dovrebbero essere definitive accessibili dalla classe anonima?

Qual è il motivo dietro la regola di avere variabili locali dichiarate come finale per accedervi da classe anonima?

+0

Duplicato di http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different (ma non di più voti ravvicinati) – skaffman

risposta

6

Quando si accede a una variabile final da una classe anonima, il compilatore copia segretamente il proprio valore in una variabile membro della classe anonima. ad esempio:

Runnable foo() { 
    final int x = 42; 
    return new Runnable() { 
    void run() { 
     System.out.writeln(x); 
    } 
    }; 
} 

diventa:

// the actual name is generally illegal in normal java syntax 
class internal_Runnable implements Runnable { 
    final int x; 
    internal_Runnable(int _x) { x = _x; } 
    void run() { 
    System.out.writeln(x); 
    } 
} 

void foo() { 
    final x = 42; 
    return new internal_Runnable(x); 
} 

Se la variabile non fosse definitiva e sono stati autorizzati a cambiare, il valore memorizzato nella cache nell'istanza classe anonima potrebbe andare fuori sincrono. Ciò avrebbe potuto essere evitato con l'uso di una chiusura, ovvero di un oggetto contenente i valori di tutte le variabili locali, che accedono sia alla funzione originale che alla nuova istanza di classe anonima. .NET uses closures, for example. Tuttavia, questo può comportare un calo di prestazioni, e forse per questo motivo, i progettisti del linguaggio Java hanno deciso di non supportare chiusure complete.

0

È perché l'oggetto interno anonimo potrebbe out-persistere il suo contesto, che, se si riferiva a non- final variabili, avrebbe quindi parlare con cose che non esistono più.

8

... quando un oggetto della classe anonima è istanziato, copie delle variabili locali finali e parametri di metodo a cui si riferisce metodi dell'oggetto sono memorizzati come variabili di istanza in oggetto. I metodi nell'oggetto della classe anonima accedono effettivamente a quelle variabili di istanza nascoste .

Pertanto, i locali variabili e parametri di metodo letta dai metodi della classe locale deve essere dichiarata finale impedire loro valori di modificare dopo che l'oggetto è un'istanza.

Da here.

1

Una classe anonima è una classe separata. Non ha accesso al flusso di controllo all'interno del tuo metodo. Se si riassegnasse la variabile nella classe anonima, in realtà si riassegnerebbe solo la copia della variabile della classe anonima. Sarebbe molto soggetta a errori e quindi la scelta progettuale è stata presa per renderlo un errore.

Se si desidera ovviare a ciò, utilizzare AtomicReference.

Problemi correlati