Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое иммутабельность
Иммутабельность (immutability) — это свойство объекта, при котором его состояние не может быть изменено после создания. Иммутабельный объект гарантирует, что все его поля остаются неизменными на протяжении всего жизненного цикла.
Зачем нужна иммутабельность
- Thread-safety — иммутабельные объекты безопасны в многопоточной среде, так как не требуют синхронизации
- Безопасность в совместном доступе — разные потоки могут безопасно делиться одним объектом
- Кеширование — можно безопасно кешировать значения
- Предсказуемость — состояние объекта не меняется неожиданно
- Функциональное программирование — основа для FP парадигмы
Правила создания иммутабельного класса
// Шаг 1: объявить класс final
public final class ImmutablePerson {
// Шаг 2: все поля private и final
private final String name;
private final int age;
private final List<String> hobbies;
// Шаг 3: инициализировать в конструкторе
public ImmutablePerson(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
// Шаг 4: защитить от внешних изменений (defensive copy)
this.hobbies = new ArrayList<>(hobbies);
}
// Шаг 5: no setters, только getters
public String getName() {
return name;
}
public int getAge() {
return age;
}
// Шаг 6: возвращать копии mutable объектов
public List<String> getHobbies() {
return new ArrayList<>(hobbies);
}
// Шаг 7: переопределить equals, hashCode, toString
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ImmutablePerson)) return false;
ImmutablePerson other = (ImmutablePerson) obj;
return Objects.equals(name, other.name) &&
age == other.age &&
Objects.equals(hobbies, other.hobbies);
}
@Override
public int hashCode() {
return Objects.hash(name, age, hobbies);
}
}
Пример использования
public class ImmutabilityExample {
public static void main(String[] args) {
List<String> hobbies = new ArrayList<>(Arrays.asList("reading", "coding"));
ImmutablePerson person = new ImmutablePerson("Alice", 30, hobbies);
// Попытка изменить список извне не повлияет на объект
hobbies.add("gaming");
System.out.println(person.getHobbies()); // [reading, coding]
// Попытка изменить возвращённый список
List<String> returned = person.getHobbies();
returned.add("gaming");
System.out.println(person.getHobbies()); // [reading, coding]
}
}
Встроенные иммутабельные классы Java
// String — иммутабельна
String str = "hello";
// str.toUpperCase() возвращает новую строку, не меняя оригинал
// Integer, Long, Double — иммутабельны
Integer num = Integer.valueOf(5);
// LocalDateTime, LocalDate — иммутабельны
LocalDateTime now = LocalDateTime.now();
LocalDateTime later = now.plusDays(1); // новый объект
// Collections.unmodifiableXXX()
List<String> unmodifiable = Collections.unmodifiableList(
new ArrayList<>(Arrays.asList("a", "b"))
);
// unmodifiable.add("c"); // UnsupportedOperationException
Иммутабельность в Java records (Java 14+)
// Record автоматически создаёт иммутабельный класс
public record Person(
String name,
int age,
List<String> hobbies
) {
// Компилятор генерирует:
// - final поля
// - конструктор
// - getters (name(), age(), hobbies())
// - equals, hashCode, toString
// Но нужно защитить mutable поле от внешних изменений
public Person {
hobbies = new ArrayList<>(hobbies);
}
}
Преимущества иммутабельности
// 1. Thread-safety без синхронизации
ImmutablePerson person1 = new ImmutablePerson("Bob", 25, List.of());
ImmutablePerson person2 = person1; // безопасно делиться между потоками
// 2. Безопасное использование в HashMap/HashSet
Set<ImmutablePerson> set = new HashSet<>();
set.add(person1);
// hashCode никогда не поменяется
// 3. Предсказуемый код
ImmutablePerson original = new ImmutablePerson("Charlie", 35, List.of());
ImmutablePerson copy = new ImmutablePerson(
original.getName(),
original.getAge(),
original.getHobbies()
);
// original и copy гарантированно равны и не изменятся
Недостатки иммутабельности
// 1. Больше объектов в памяти (new для каждого изменения)
ImmutablePerson person = new ImmutablePerson("David", 40, List.of());
// для изменения возраста нужен новый объект
ImmutablePerson updated = new ImmutablePerson("David", 41, List.of());
// 2. Сложнее работать с большими объектами
// Часто используют Builder pattern
public class PersonBuilder {
private String name;
private int age;
private List<String> hobbies = new ArrayList<>();
public PersonBuilder withName(String name) {
this.name = name;
return this;
}
public ImmutablePerson build() {
return new ImmutablePerson(name, age, hobbies);
}
}
Вывод
Иммутабельность — один из ключевых принципов функционального программирования. Используй её для:
- Значимых объектов (Entity, Value Objects)
- Многопоточного кода
- Кешируемых данных
- Ключей в HashMap/HashSet