Когда вы получаете доступ к переменной final
из анонимного класса, компилятор тайно копирует свое значение в переменную-член анонимного класса. например:
Runnable foo() {
final int x = 42;
return new Runnable() {
void run() {
System.out.writeln(x);
}
};
}
становится:
// 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);
}
Если переменная не были окончательными и позволили изменить значение в кэше в экземпляре анонимного класса может выйти из синхронизации. Этого можно избежать, используя закрытие, то есть объект, содержащий значения всех локальных переменных, которые имеют как исходная функция, так и новый экземпляр анонимного класса. .NET uses closures, for example. Однако это может привести к поражению производительностью, и, возможно, по этой причине разработчики языка Java решили не поддерживать полное закрытие.
Дубликат http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different (но не более близкие голоса) – skaffman