Назад к вопросам
Middle
69
questionbank

Как сделать класс в Java неизменяемым?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Чтобы сделать класс в Java неизменяемым (immutable), следует придерживаться следующих принципов:

  1. Пометить класс как final. Это предотвратит наследование, которое может привести к изменению состояния.
  2. Сделать все поля класса приватными (private). Это ограничит прямой доступ к полям извне класса.
  3. Не предоставлять сеттеры (методы для изменения состояния полей).
  4. Сделать все изменяемые поля класса final. Это гарантирует, что ссылки на изменяемые объекты не могут быть изменены после инициализации.
  5. Если класс содержит ссылки на изменяемые объекты (например, java.util.Date, коллекции), при возврате из геттеров или передаче в конструктор, следует создавать и возвращать копии этих объектов. Это называется "глубокое копирование".

Пример:

// Пример неизменяемого класса
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;
        // Создаем копию списка hobbies
        this.hobbies = new ArrayList<>(hobbies);
    }

    // Геттеры
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    // Возвращаем копию списка hobbies для предотвращения изменений извне
    public List<String> getHobbies() {
        return Collections.unmodifiableList(new ArrayList<>(this.hobbies));
    }

    // Переопределение toString для удобства
    @Override
    public String toString() {
        return "ImmutablePerson{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", hobbies=" + hobbies +
               '}';
    }
}

Пример использования:

// Пример использования неизменяемого класса
List<String> initialHobbies = new ArrayList<>();
initialHobbies.add("Reading");
initialHobbies.add("Hiking");

ImmutablePerson person = new ImmutablePerson("Alice", 30, initialHobbies);

// Попытка изменить полученный список приведет к исключению
List<String> retrievedHobbies = person.getHobbies();
// retrievedHobbies.add("Coding"); // Вызовет UnsupportedOperationException

// Изменение исходного списка не повлияет на объект ImmutablePerson
initialHobbies.add("Painting");

System.out.println(person); // Вывод: ImmutablePerson{name='Alice', age=30, hobbies=[Reading, Hiking]}
System.out.println(initialHobbies); // Вывод: [Reading, Hiking, Painting]