Я до сих пор не удовлетворен объяснением анонимного класса и конечного поля. Были тонны вопросов, пытаясь объяснить очевидную проблему, но я не нашел ответы на все мои вопросы :-)Заключительное поле и анонимный класс
Пусть следующий код:
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);
}
};
}
- Это невозможно скомпилировать этот код из-за " unfinal "
k
Недвижимость. - Я понимаю, что компилятор может заменить свойство
z
с объявленным значением во время компиляции.
Когда я искал решение, как именно может работает i
и x
я нашел этот answer, который говорит:
компилятор может затем просто заменить использование lastPrice и цену в анонимном классе с значения констант (во время компиляции, конечно), и вы не будете иметь проблем с доступом несуществующих переменными больше
Как это может работать на поля i
и x
если они являются параметрами метода? Они не известны во время компиляции? Этот подход может работать для z
.
С другой стороны, есть объяснение относительно stack issues:
Это позволяет компилятору Java, чтобы «захватить» значение переменной во время выполнения и сохранить копию как поле во внутреннем класс. После того, как внешний метод завершается и его кадр стека был удален, исходные переменный исчезают, но частная копия внутреннего класса в упорствует в собственной памяти класса
Я понимаю, что анонимный класс как-то скопировал все необходимое содержание (поля) во время его создания. Отсутствие final
имеет очевидную проблему: если какой-то код ниже, объявление анонимного класса изменит значение, возможно выполнение с использованием stale
значений.
Но это должно решить проблему, когда метод анонимного класса выполняется из области использования используемых свойств.
Но этот подход должен работать даже без объявления final
, поскольку он просто копирует все поля.
Оба подхода кажутся независимыми для меня. Говоря о котором - и он мог решить мои вопросы - я не нашел, как работает поле метода final
. Они не удаляются из стека, даже если метод завершается? Для меня это похоже, но это объясняет много вещей :-)
Каков правильный ответ?
Спасибо за разъяснение. Так я думаю об этом. Поэтому я не понимаю, почему он должен быть определен как «final», когда анонимное создание просто использует моментальный снимок всех используемых свойств и всех. Этот подход работает даже без ключевого слова final, как я писал в моем вопросе. –
Может быть, я этого не понял, но ваш второй пример можно было бы написать без объявления обеих переменных как «final», а первый требует, чтобы 'x' был объявлен окончательным из-за использования внутри анонимного класса, - и это то, что OP попросил нас уточнить. – alfasin
@MartinPodval: Посмотрите, помогает ли мое редактирование ... –