2011-01-24 15 views
9

Duplicar posibles:
Cannot refer to a non-final variable inside an inner class defined in a different method¿Por qué mis variables locales deben ser finales para ser accesibles desde una clase anónima?

¿Cuál es la razón detrás de la regla de tener variables locales declaradas como definitivo con el fin de acceder a ellos desde clase anónima?

+0

Duplicado de http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different (pero no más cerrar votos) – skaffman

Respuesta

6

Cuando accede a una variable final de una clase anónima, el compilador copia secretamente su valor en una variable miembro de la clase anónima. por ejemplo:

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

se convierte en:

// 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); 
} 

Si la variable no eran definitivas y se les permitió cambiar, el valor almacenado en caché en la instancia de clase anónimo podría ir fuera de sincronización. Esto podría haberse evitado mediante el uso de un cierre, es decir, un objeto que contenga los valores de todas las variables locales, al que acceden tanto la función original como la nueva instancia de clase anónima. .NET uses closures, for example. Sin embargo, esto puede incurrir en un golpe de rendimiento, y tal vez por esa razón, los diseñadores de lenguaje de Java decidieron no admitir cierres completos.

0

Es porque el objeto interna anónima podría persistir fuera de su contexto, que, si se refería a la no final las variables, entonces tendría que hablar con las cosas que no existen más.

8

... cuando se instancia un objeto de la clase anónima , copias de las variables locales finales y los parámetros del método que se hace referencia por los métodos del objeto se almacenan como variables de instancia en el objeto. Los métodos en el objeto de la clase anónima realmente acceden a las variables de instancia ocultas .

Por lo tanto, los locales variables y Parámetros de métodos visitada por los métodos de la clase local debe declararse final a evitar que sus valores de cambio de después de que el objeto se crea una instancia.

De here.

1

Una clase anónima es una clase separada. No tiene acceso al flujo de control dentro de su método. Si reasigna la variable en la clase anónima, en realidad solo reasignaría la copia de la clase anónima de la variable. Eso sería muy propenso a errores, y por lo tanto, la elección del diseño se hizo para convertirlo en un error.

Si quiere evitar esto, use un AtomicReference.

Cuestiones relacionadas