Что такое иммутабельные (неизменяемые) объекты в Java?

Ответ

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

Как создать иммутабельный класс в Java:

  1. Объявите класс как final, чтобы запретить наследование.
  2. Объявите все поля как private и final.
  3. Инициализируйте поля только в конструкторе.
  4. Не предоставляйте сеттеров (методов, изменяющих поля).
  5. Для полей-ссылок на изменяемые объекты:
    • Не возвращайте сам объект в геттерах (возвращайте его глубокую копию).
    • В конструктор также передавайте копию объекта.

Пример:

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);
    }
}

Преимущества:

  • Потокобезопасность: Не требуют синхронизации.
  • Предсказуемость: Состояние гарантированно не изменится.
  • Надежность: Упрощают отладку и рассуждения о коде.
  • Безопасное кэширование и повторное использование.

Стандартные примеры: String, классы-обертки (Integer, Long).

Ответ 18+ 🔞

Да ты посмотри на эту красоту, блядь! Иммутабельный объект — это как монах, давший обет молчания, только в мире кода. Создали его, а он тебе: "Всё, я готов, я совершенен, не трогай меня, ёпта!". Состояние его менять — ни-ни, после создания всё, пиздец, точка.

Как сварганить такой несгибаемый класс на Java, чтобы все ахуели:

  1. Класс в final загони, чтоб никакой умник-наследник не приплелся со своими кривыми правками. Стоп-кран, блядь.
  2. Все поля — private да final. Приватные, чтобы соседи не лапали, и финальные, чтоб один раз и навсегда, как татуха на пояснице.
  3. Инициализация — только в конструкторе, один шанс, как в русской рулетке. Проебал — сиди с пустышкой.
  4. Сеттеров нихуя! Вообще выбрось эту мысль из головы. Захотел поменять значение? Создавай новый объект, лентяй ебаный.
  5. А вот тут, сука, самое интересное, с полями-ссылками. Если там лежит, например, List или какой HashMap — это же изменяемая хуйня! Они тебе всю концепцию разнесут в щепки.
    • В геттере не возвращай оригинал, а то какой-то пидор его возьмёт и начнёт там add() или remove() делать. Возвращай копию, глубокую, чтоб наверняка.
    • В конструктор тоже не сам список пихай, а его копию. Подстрахуйся, блядь!

Смотри, как это выглядит вживую:

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); // Чистая копия, ебать её в сраку!
    }
}

И зачем этот цирк, спросишь? А преимущества-то, блядь, овердохуищные:

  • Потокобезопасность на халяву. Кидай его двадцати потокам — они могут его только читать. Никаких synchronized, mutex, semaphore — красота, ёпта!
  • Предсказуемость полная. Создал — и спи спокойно. Он не изменится, пока тебе ночной кошмар не приснится.
  • Надёжность, как швейцарские часы. Отлаживать — одно удовольствие, рассуждать о коде — проще пареной репы.
  • Кэшировать можно без задней мысли и повторно использовать. Как кирпич — взял с кучи и поставил в другую стену.

Стандартные примеры, которые все знают, но не все ценили: String (вот кто главный мутант-иммутабл), все эти Integer, Long — они все такие же стойкие оловянные солдатики.