Ответ
Иммутабельный объект — это объект, состояние которого нельзя изменить после создания.
Как создать иммутабельный класс в Java:
- Объявите класс как
final, чтобы запретить наследование. - Объявите все поля как
privateиfinal. - Инициализируйте поля только в конструкторе.
- Не предоставляйте сеттеров (методов, изменяющих поля).
- Для полей-ссылок на изменяемые объекты:
- Не возвращайте сам объект в геттерах (возвращайте его глубокую копию).
- В конструктор также передавайте копию объекта.
Пример:
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, чтобы все ахуели:
- Класс в
finalзагони, чтоб никакой умник-наследник не приплелся со своими кривыми правками. Стоп-кран, блядь. - Все поля —
privateдаfinal. Приватные, чтобы соседи не лапали, и финальные, чтоб один раз и навсегда, как татуха на пояснице. - Инициализация — только в конструкторе, один шанс, как в русской рулетке. Проебал — сиди с пустышкой.
- Сеттеров нихуя! Вообще выбрось эту мысль из головы. Захотел поменять значение? Создавай новый объект, лентяй ебаный.
- А вот тут, сука, самое интересное, с полями-ссылками. Если там лежит, например,
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 — они все такие же стойкие оловянные солдатики.