← Назад к вопросам

Является ли класс final полностью иммутабельным?

1.8 Middle🔥 161 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Является ли класс final полностью иммутабельным?

Нет, объявление класса как final не делает его автоматически иммутабельным. Это частая ошибка в понимании. final ограничивает только наследование, но не гарантирует неизменяемость содержимого класса.

Что делает final?

Модификатор final на уровне класса предотвращает наследование:

final class ImmutableExample {  // нельзя создать подкласс
    private String name;
    private int age;
}

// Это вызовет ошибку компиляции
class SubClass extends ImmutableExample {  // ОШИБКА
}

Однако внутри класса поля по-прежнему остаются изменяемыми, если они не объявлены как final:

final class MyClass {
    private String name;  // Может быть изменено!
    
    public void setName(String name) {
        this.name = name;  // Изменяемость сохранена
    }
}

Требования для истинной иммутабельности

Для создания по-настоящему неизменяемого класса нужно:

  1. Объявить класс как final - чтобы нельзя было создать подкласс
  2. Все поля объявить как private final
  3. Инициализировать все поля в конструкторе
  4. Не предоставлять сеттеры
  5. Осторожно с мутабельными объектами
final class TrulyImmutable {
    private final String name;
    private final int age;
    private final List<String> hobbies;
    
    public TrulyImmutable(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        this.hobbies = Collections.unmodifiableList(
            new ArrayList<>(hobbies)
        );
    }
    
    public List<String> getHobbies() {
        return hobbies;
    }
}

Пример полностью иммутабельного класса

final class Person {
    private final String name;
    private final int age;
    private final LocalDate birthDate;
    
    public Person(String name, int age, LocalDate birthDate) {
        this.name = Objects.requireNonNull(name);
        this.age = age;
        this.birthDate = Objects.requireNonNull(birthDate);
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public LocalDate getBirthDate() {
        return birthDate;
    }
}

Почему это важно?

Преимущества иммутабельности:

  • Thread-safe по умолчанию - несколько потоков могут безопасно использовать объект
  • Безопасность кеширования - можно переиспользовать объекты
  • Простота отладки - состояние не меняется после создания
  • Использование в HashMap - иммутабельные объекты безопасны как ключи

Проверка: является ли класс иммутабельным?

  • final класс + все поля final + нет сеттеров = иммутабельный
  • final класс БЕЗ final полей = мутабельный
  • Обычный класс БЕЗ final = может быть наследован

Вывод: final - необходимое, но недостаточное условие для иммутабельности.

Является ли класс final полностью иммутабельным? | PrepBro