Причина, по которой вы должны сделать локальные переменные final
, заключается в том, что Java копирует их значения в экземпляр внутреннего класса. За кулисами происходит то, что компилятор генерирует байт-код, который (примерно) соответствует этому:
class ClassInMethod {
public static void main(String[] args) {
int local = 1;
// this happens when you do: new Inner()
ClassInMethod_main_Inner inner = new ClassInMethod_main_Inner();
inner.local = local;
}
}
// the inner class
class ClassInMethod_main_Inner {
int local;
public void method() {
System.out.println(local);
}
}
Если local
не было final
, и вы можете изменить его значение между моментом создания экземпляра Inner
и вызовом method()
, при вызове method()
будет использоваться старое значение local
. Это, вероятно, будет неправильным поведением. final
обязана сделать интуитивно понятным поведение внутренних классов.
(Существуют языки, которые не имеют этого ограничения, но требуют явной поддержки со стороны компилятора и среды выполнения. Разработчики Java до сих пор не решили посвятить свои усилия его реализации.)