Что такое иммутабельный объект в Java? Приведите пример его реализации.

Ответ

Иммутабельный (неизменяемый) объект — это объект, состояние которого нельзя изменить после создания. Это фундаментальная концепция для написания потокобезопасного и предсказуемого кода.

Пример реализации на Java:

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

// 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. Создаем защитную копию для изменяемых полей
        this.hobbies = new ArrayList<>(hobbies);
    }

    // 5. Только геттеры, без сеттеров
    public String getName() { return name; }
    public int getAge() { return age; }
    // 6. Геттер для коллекции возвращает неизменяемое представление
    public List<String> getHobbies() {
        return Collections.unmodifiableList(hobbies);
    }
}

Ключевые принципы:

  1. final класс — запрещает наследование и переопределение методов.
  2. final поля — гарантируют однократную инициализацию.
  3. Нет сеттеров — отсутствует публичный API для модификации.
  4. Защитное копирование — в конструкторе и геттерах для изменяемых внутренних объектов (массивы, коллекции).
  5. Возврат неизменяемых представлений — например, через Collections.unmodifiableList().

Преимущества: потокобезопасность без синхронизации, простота кэширования и отладки, безопасное использование в качестве ключей HashMap.

Ответ 18+ 🔞

А, вот эта тема про иммутабельность! Ну, блядь, классика, как Герасим с Муму, только в мире кода. Слушай, представь себе объект, который, как тот самый немой Герасим, — раз создался, так уже нихуя не изменится. Ни "му", ни "му". Засунули ему в поля данные при рождении — и всё, пиши пропало, приехали. Это и есть иммутабельный объект, сука, этакий каменный гость в твоей программе.

Ну, вот смотри, как его на Java слепить, чтобы он был крепче, чем совесть у того же Герасима после... ну, ты понял.

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

// 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. А тут, внимание, ебушки-воробушки! Делаем защитную копию! Берём тот список, что нам передали, и создаём НОВЫЙ, блядь, ArrayList, копируя всё внутрь.
        // А то вдруг нам передали ссылку на список, а потом кто-то извне этот список будет пилить и менять? Пиздец нашему иммутабельному идиллию!
        this.hobbies = new ArrayList<>(hobbies);
    }

    // 5. Только геттеры! Сеттеров — ноль ебать! Куда уж тут меняться-то?
    public String getName() { return name; }
    public int getAge() { return age; }
    // 6. И вот самый сок, блядь! Геттер для списка возвращает НЕИЗМЕНЯЕМОЕ представление!
    // Коллекции.unmodifiableList() — это такая волшебная обёртка, которая говорит: "Смотрить можно, трогать — низя! Попробуешь add() или remove() — получишь UnsupportedOperationException прямо в ебало!"
    public List<String> getHobbies() {
        return Collections.unmodifiableList(hobbies);
    }
}

И что за хуйня получается, спросишь ты? А получается объект, который, как тот самый здоровенный немой татарин, — силён и предсказуем. Его можно тыкать в десять потоков одновременно, и он никого не ебнёт по ебалу неожиданным изменением состояния. Его можно смело использовать как ключ в HashMap — он не сдвинется с места, как ядро́-чистый изумруд. Отлаживать его — одно удовольствие, потому что он с момента рождения и до смерти — один и тот же мудак. Короче, красота, а не концепция, в рот меня чих-пых!