51. Сделать класс immutable
Условие задачи:
Дан класс A с полями Integer a и List<Object> b. Необходимо сделать его неизменяемым.
Код:
class A {
Integer a;
List<Object> b;
}
Спойлеры к решению
Подсказки
💡 Запрети наследование от класса.
💡 Сделай все поля
💡 Устанавливай значения только через конструктор.
💡 Не добавляй сеттеры.
💡 Создавай защитную копию изменяемой коллекции.
💡 Учитывай, что копирование списка не делает неизменяемыми его элементы.
💡 Сделай все поля
private final.💡 Устанавливай значения только через конструктор.
💡 Не добавляй сеттеры.
💡 Создавай защитную копию изменяемой коллекции.
💡 Учитывай, что копирование списка не делает неизменяемыми его элементы.
Решение
public final class A {
private final Integer a;
private final List<Object> b;
public A(Integer a, List<Object> b) {
this.a = a;
this.b = b == null
? List.of()
: List.copyOf(b);
}
public Integer getA() {
return a;
}
public List<Object> getB() {
return b;
}
}
Класс нельзя унаследовать, его поля нельзя переназначить после создания, а список копируется и хранится в неизменяемом виде.
Изменение исходного списка не повлияет на состояние объекта:
List<Object> source = new ArrayList<>();
source.add("value");
A object = new A(10, source);
source.add("another");
System.out.println(object.getB()); // [value]
Попытка изменить список через геттер завершится исключением:
object.getB().add("new value");
List.copyOf() выполняет поверхностное копирование. Поэтому для полной неизменяемости элементы списка тоже должны быть immutable. Если внутри находятся изменяемые объекты, для них необходимо создавать глубокие защитные копии.