— Привіт, Аміго!

— Сьогодні говоримо про mutable та immutable об'єкти.

Об'єкти, які після створення можна змінити, називаються змінними або mutable.

Об'єкти, які після їх створення змінити не можна, називаються незмінними або immutable.

— А від чого залежить, можна об'єкт змінювати чи ні?

— Людина, яка пише новий клас, може зробити об'єкти цього класу незмінними. Наприклад, можна приховати усі setter’и — в об'єкта буде тільки конструктор і getter’и, отже, після створення об'єкта змінити його вже не можна.

— І яка від цього користь?

—У незмінних об'єктів багато корисних властивостей. Але можна виділити два, які характерні практично для всіх immutable-об'єктів:

1) Незмінні об'єкти можна реалізувати значно простіше, ніж змінні.

2) Незмінні об'єкти можна вільно використовувати одночасно з різних потоків.

Найчастіше, коли розробник вирішує написати immutable клас, він робить дві версії цього класу — mutable та immutable.

— А в чому сенс писати два класи замість одного?

— Іноді так вигідніше, коли незмінна версія об'єкта буде набагато простішою/швидшою, ніж змінна. Тоді й роблять дві версії. Це майже як ArrayList і LinkedList: обидва — списки, але один оптимізований для одних цілей, другий — для інших.

— Вже зрозуміліше.

— Бувають також і чисто immutable класи, без їхньої mutable версії.

— А якщо мені потрібно щось змінити у такому об'єкті? Що взагалі можна зробити з незмінним об'єктом?

— Зазвичай immutable класи містять різні методи, які «начебто» змінюють об'єкт, але замість зміни самого об'єкта ці методи просто створюють новий об'єкт і повертають його.

Ось тобі кілька прикладів:

Код на Java Опис
String s = "kyiv";
String s2 = s.toUpperCase();
В результаті s містить рядок «kyiv», а s2 — «KYIV»
Integer i = 1;
Integer j = i;
j++;
Ось що відбувається насправді:
Integer i = new Integer(1);
Integer j = i;
j = new Integer(i.getInt()+1);

Клас String — це immutable клас. Усі об'єкти типу String — незмінні, що, однак, не заважає нам з ними працювати. Наприклад, метод toUpperCase() класу String перетворює рядок у верхній реєстр (замінює всі маленькі літери на великі). Але цей метод не змінює сам рядок, а повертає новий рядок, який ідентичний першому, тільки усі символи у верхньому реєстрі (великі).

Клас Integer — це теж immutable клас. Усі об'єкти типу Integer — незмінні. Щоразу, коли ми змінюємо об'єкт Integer, насправді створюється новий об'єкт.