Финальное поле и анонимный класс
Я все еще не удовлетворен объяснением относительно анонимного класса и заключительного поля. Было множество вопросов, пытающихся объяснить очевидную проблему, но я не нашел ответов на все мои вопросы :-)
Предположим, следующий код:
public void method(final int i, int j) {
final int z = 6;
final int x = j;
int k = 5;
new Runnable() {
public void run() {
System.out.print(i);
System.out.print(x);
System.out.print(z);
System.out.print(k);
}
};
}
Невозможно скомпилировать этот код из-за "нефинала"k
свойство.Я понимаю, что компилятор может заменитьz
свойство с объявленным значением во время компиляции.Когда я искал решение, как именно может работатьi
а такжеx
я нашел этоответ который говорит:
Затем компилятор может просто заменить использование lastPrice и price в анонимном классе значениями констант (во время компиляции, конечно), и у вас больше не будет проблем с доступом к несуществующим переменным
Как это может работать для полейi
а такжеx
если они являются параметрами метода? Они не известны во время компиляции? Этот подход может работать дляz
.
С другой стороны, есть объяснение относительнопроблемы со стеком:
Это позволяет компилятору Java «захватывать» значение переменной во время выполнения и сохранять копию в виде поля во внутреннем классе. После завершения внешнего метода и удаления его стекового фрейма исходная переменная исчезает, но личная копия внутреннего класса сохраняется в собственной памяти класса.
Я бы понял, что анонимный класс каким-то образом копировал весь необходимый контент (поля) при его создании. Отсутствуетfinal
есть очевидная проблема, что если какой-то кодниже объявление анонимного класса изменит значение, возможно, будет использовано выполнениеstale
ценности.
Но хорошо, это должно решить проблему, когда метод анонимного класса выполняется вне области используемых свойств.
Но этот подход должен работатьчетный безfinal
декларация, так как он просто копирует все поля.
Оба подхода кажутся мне независимыми. Говоря о том, что - и это может решить мои вопросы - я не нашел, как работаютfinal
поле метода. Они не удаляются из стека, даже если метод завершен? Для меня это чушь, но это многое объясняет :-)
Какой правильный ответ?