Показанный класс уже копирует список и не отдаёт изменяемый доступ к нему. Чтобы закрыть расширение поведения через наследование, сделайте сам Element final.
Как преобразовать обычный класс в неизменяемый объект
Показанный класс уже копирует список и не отдаёт изменяемый доступ к нему. Чтобы закрыть расширение поведения через наследование, сделайте сам Element final.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Требуется изменить данный класс так, чтобы его экземпляры стали полностью неизменяемыми. Для этого необходимо:
- убрать все сеттеры;
- объявить поля как
final; - при передаче изменяемых объектов (например, списков) создавать их копии, чтобы внешние изменения не влияли на внутреннее состояние;
- обеспечить безопасный доступ к полям через только геттеры.
Ниже приведён исходный код, который нужно адаптировать к требованиям иммутабельности. Вы можете переименовать переменные, но структура и логика должны остаться прежними.
public class Element {
private final int number;
private final List<String> items;
public Element(int number, List<String> items) {
this.number = number;
// создаём копию списка, чтобы предотвратить внешние модификации
this.items = new ArrayList<>(items);
}
public int getNumber() {
return number;
}
public List<String> getItems() {
// возвращаем неизменяемый вид списка
return Collections.unmodifiableList(items);
}
}
После этих изменений объекты Element будут гарантированно неизменяемыми: их состояние нельзя будет изменить после создания, а любые попытки модифицировать внутренний список приведут к UnsupportedOperationException.
Ответ
Показанный класс уже копирует список и не отдаёт изменяемый доступ к нему. Чтобы закрыть расширение поведения через наследование, сделайте сам Element final.
public final class Element {
private final int number;
private final java.util.List<String> items;
public Element(int number, java.util.List<String> items) {
this.number = number;
this.items = java.util.Collections.unmodifiableList(
new java.util.ArrayList<>(items));
}
public int getNumber() { return number; }
public java.util.List<String> getItems() { return items; }
}
String неизменяем, поэтому достаточно копии контейнера. List.copyOf короче, но дополнительно запрещает null-элементы, меняя контракт исходника. Если вместо строк появятся изменяемые объекты, одной поверхностной копии списка уже будет недостаточно.