Как отмечается в комментариях, часть этого становится неактуальной в Java 8, где final
может быть неявным.Однако в анонимном внутреннем классе или лямбда-выражении можно использовать только эффективно конечную переменную.
В основном это связано с тем, как Java управляет замыканиями .
Когда вы создаете экземпляр анонимного внутреннего класса, любые переменные, которые используются в этом классе, имеют значения , скопированные через автоматически сгенерированный конструктор.Это избавляет компилятор от необходимости автоматически генерировать различные дополнительные типы для хранения логического состояния «локальных переменных», как, например, это делает компилятор C # ... (Когда C # захватывает переменную в анонимной функции, он действительно захватывает переменную -Закрытие может обновить переменную таким образом, который виден основной частью метода, и наоборот.)
Поскольку значение было скопировано в экземпляр анонимного внутреннего класса, это выглядело бы странно, если быпеременная может быть изменена остальной частью метода - у вас может быть код, который, кажется, работает с устаревшей переменной (потому что это действительно то, что будет происходить ... вы быработа с копией, сделанной в другое время).Аналогично, если бы вы могли вносить изменения в анонимном внутреннем классе, разработчики могли бы ожидать, что эти изменения будут видны в теле включающего метода.
Преобразование финальной переменной удаляет все эти возможности - поскольку значение не может бытьизменилось, вам не нужно беспокоиться о том, будут ли такие изменения видны.Единственный способ позволить методу и анонимному внутреннему классу видеть изменения друг друга - это использовать изменяемый тип некоторого описания.Это может быть сам класс включения, массив, изменяемый тип-обертка ... что-нибудь в этом роде.По сути, это немного похоже на обмен данными между одним методом и другим: изменения, внесенные в параметры одного метода, не видны его вызывающей, но изменения, внесенные в объекты , на которые ссылается параметры видны.
Если вас интересует более подробное сравнение между замыканиями Java и C #, у меня есть статья , которая углубляется в это.Я хотел сосредоточиться на стороне Java в этом ответе:)