Что такое иммутабельность (immutability) в программировании?

«Что такое иммутабельность (immutability) в программировании?» — вопрос из категории ООП, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Иммутабельность — это свойство объекта, означающее, что его состояние нельзя изменить после создания. Любая операция, которая должна изменить объект, возвращает новый объект с обновлённым состоянием, оставляя исходный неизменным.

Зачем это нужно?

  • Потокобезопасность: Иммутабельные объекты можно безопасно использовать в многопоточных средах без блокировок.
  • Предсказуемость: Поведение кода становится более предсказуемым, так как объект не может неожиданно измениться в другой части программы.
  • Простота отладки и тестирования: Состояние объекта фиксировано.
  • Кеширование и повторное использование: Иммутабельные объекты с одинаковым состоянием могут быть одним и тем же объектом (как строки в пуле строк Java).

Пример в Java:

// Мутабельный класс
class MutablePoint {
    public int x, y;
    public MutablePoint(int x, int y) { this.x = x; this.y = y; }
}
MutablePoint p1 = new MutablePoint(1, 2);
MutablePoint p2 = p1; // p2 ссылается на тот же объект
p2.x = 10;
System.out.println(p1.x); // Выведет 10! p1 изменился неожиданно.

// Иммутабельный класс
final class ImmutablePoint {
    private final int x;
    private final int y;
    public ImmutablePoint(int x, int y) { this.x = x; this.y = y; }
    public int getX() { return x; }
    public int getY() { return y; }
    // Операция "изменения" возвращает новый объект
    public ImmutablePoint withX(int newX) {
        return new ImmutablePoint(newX, this.y);
    }
}
ImmutablePoint ip1 = new ImmutablePoint(1, 2);
ImmutablePoint ip2 = ip1.withX(10); // Создаётся новый объект
System.out.println(ip1.getX()); // Осталось 1
System.out.println(ip2.getX()); // Новое значение 10

В Java иммутабельность достигается через ключевое слово final для класса и полей, отсутствие сеттеров и возврат новых экземпляров в методах-модификаторах. Классы String, Integer, LocalDate являются иммутабельными.