Collections.unmodifiableList() не даёт иммутабельность — это view
Метод оборачивает список в неизменяемую обёртку: вызов add() или remove() на результате бросает UnsupportedOperationException. Кандидаты часто останавливаются на этом и называют список полностью иммутабельным.
На деле unmodifiableList() — это view над тем же backing-массивом. Обёртка запрещает мутацию только через себя. Если где-то в коде осталась прямая ссылка на исходный List, содержимое поменяется и в обёртке — это один и тот же объект в памяти.
List source = new ArrayList<>( List.of("a", "b") );
List view = Collections .unmodifiableList(source);
source.add("c");
System.out.println(view.size()); // 3, а не 2
Настоящая иммутабельность — List.of() или List.copyOf(): они копируют данные при создании, а не оборачивают чужую ссылку.
Следом спросят: а List.copyOf() всегда копирует? Нет — если аргумент уже неизменяемый список, созданный тем же API, copyOf() может вернуть его же без копии, потому что мутировать его и так нельзя.
unmodifiableList() защищает от чужого API, а не от кода, у которого есть исходная ссылка на список.
Тренажёр: 600 вопросов, мок с таймером, план повторов
senior·base — что спрашивают на самом деле
В этом посте были ссылки, но мы их удалили по правилам Сетки