Ответ
Иммутабельный объект — это объект, состояние (значения его полей) которого нельзя изменить после создания. Любая операция, которая кажется модификацией, на самом деле создает новый объект.
Ключевые характеристики и преимущества:
- Потокобезопасность (Thread-safe): Поскольку состояние объекта неизменно, его можно свободно использовать в многопоточных средах без синхронизации. Несколько потоков могут читать данные одновременно без риска конфликтов.
- Простота и предсказуемость: Упрощает рассуждения о коде. Гарантируется, что объект, переданный в метод, не будет изменен где-то еще.
- Безопасное кэширование и повторное использование: Объекты можно безопасно кэшировать и использовать как константы. Классический пример —
Stringи пул строк в Java. - Надежные ключи для коллекций: Идеально подходят для использования в качестве ключей в
HashMapилиHashSet, так как ихhashCode()не изменяется.
Правила создания иммутабельного класса в Java:
- Объявите класс как
final, чтобы от него нельзя было наследоваться. - Объявите все поля как
privateиfinal. - Не предоставляйте сеттеров (setter methods).
- Если класс содержит поля-ссылки на изменяемые объекты, в конструкторе и геттерах создавайте защитные копии (defensive copies).
Пример:
import java.util.*;
public final class ImmutablePerson {
private final String name;
private final int age;
private final List<String> hobbies; // Изменяемый объект!
public ImmutablePerson(String name, int age, List<String> hobbies) {
this.name = name;
this.age = age;
// Защитная копия при инициализации
this.hobbies = new ArrayList<>(hobbies);
}
public String getName() { return name; }
public int getAge() { return age; }
// Защитная копия при возврате значения
public List<String> getHobbies() {
return new ArrayList<>(hobbies);
}
}
// Использование
ImmutablePerson person = new ImmutablePerson("Alice", 30, Arrays.asList("Reading", "Cycling"));
// person.getHobbies().add("Hacking"); // Не изменит оригинальный список hobbies