Можно ли изменять состояние объекта, на который ссылается effectively final переменная в Java?

«Можно ли изменять состояние объекта, на который ссылается effectively final переменная в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, можно. Ключевое понятие effectively final относится только к самой ссылке на объект, а не к его внутреннему состоянию.

  • Effectively final означает, что переменной присваивается значение только один раз, и ссылка больше не меняется.
  • Изменение состояния объекта через эту ссылку разрешено.

Пример:

// Переменная 'list' является effectively final (и даже явно final).
final List<String> list = new ArrayList<>();

// МОЖНО: Изменение состояния объекта (добавление элемента).
list.add("Hello");
list.add("World");
list.set(0, "Hi");

// НЕЛЬЗЯ: Переприсвоение ссылки на новый объект.
// list = new ArrayList<>(); // Ошибка компиляции: cannot assign a value to final variable 'list'

Почему это важно для лямбд и внутренних классов? Java требует, чтобы переменные, захваченные из окружающей области видимости в анонимный класс или лямбда-выражение, были final или effectively final. Это требование гарантирует, что ссылка останется валидной. Изменять состояние объекта по этой ссылке внутри лямбды также допустимо, но требует осторожности из-за проблем с потокобезопасностью.