2011-01-24 3 views
9

Можно создать дубликат:
Cannot refer to a non-final variable inside an inner class defined in a different methodПочему мои локальные переменные должны быть окончательными, чтобы быть доступными из анонимного класса?

Что является причиной правила, имеющие локальные переменные, объявленные в качестве окончательного для того, чтобы получить к ним доступ из анонимного класса?

+0

Дубликат http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different (но не более близкие голоса) – skaffman

ответ

6

Когда вы получаете доступ к переменной 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 решили не поддерживать полное закрытие.

0

Это связано с тем, что анонимный внутренний объект может выдержать свой контекст, который, если бы он ссылался на переменные не final, затем заставил бы его говорить с вещами, которые больше не существуют.

8

... когда объект анонимного класса конкретизируется, копии конечных локальных переменных и параметров методов, на которые ссылается методы объекта сохраняются как переменные экземпляра в объекте. Методы в объекте анонимного класса действительно получают доступ к скрытым переменным экземпляра.

Таким образом, местные переменных и параметры метода доступа к методам локального класса должен быть объявлен финал предотвратить их значение от изменения после того экземпляра объекта.

От here.

1

Анонимный класс - это отдельный класс. Он не имеет доступа к потоку управления внутри вашего метода. Если вы переадресовываете переменную в анонимном классе, вы на самом деле должны переназначить только копию экземпляра анонимного класса. Это было бы очень подвержено ошибкам, и, следовательно, выбор дизайна был сделан, чтобы сделать его ошибкой.

Если вы хотите обойти это, используйте AtomicReference.

Смежные вопросы

 Смежные вопросы