Вероятно, это не оптимальный выбор дизайна. В Java 8 наряду с лямбда-выражением это требование final
, будем надеяться, будет отброшено.
Цель - запретить присваивание локальной переменной из анонимного класса. Но это не требует маркировки локальной переменной как окончательной.
void f()
Object var = ...;
new Anon(){
...
print(var); // reading is ok
var = x; // error, can't write to var [1]
}
Компилятор фактически создает копию переменной var и сохраняет ее в анонимном классе. Анонимный класс получает доступ к копии только потом. Код выше фактически преобразован в
void f()
Object var = ...;
new Anon$1(var);
class Anon$1
{
final Object $var;
Anon$1(Object var){ this.$var=var; }
...
print($var);
$var = x; // error, naturally [2]
}
Как видите, нет технических причин требовать, чтобы var
было окончательным. Все, что должен сделать компилятор, когда он сталкивается с [2], зная, что $var
является синтезированным полем для var
, сообщает об ошибке «локальная переменная var не может быть назначена анонимным классом» (вместо «$ var is final») и не может быть назначен на ")
Дизайнеры языка решили нас раздражать, потребовав ключевое слово final
для локальной переменной; Я не помню обоснование; в общем, Java не боялась многословия, если желательна ясность.