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

Является ли класс-обёртка изменяемым типом данных?

1.6 Junior🔥 181 комментариев
#Основы Java

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

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

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

Являются ли классы-обёртки изменяемыми типами данных?

Краткий ответ

Нет, классы-обёртки (wrapper classes) в Java являются неизменяемыми (immutable) типами данных. Это фундаментальное свойство, которое нужно хорошо понимать при работе с Integer, Long, Double, Boolean и другими обёртками примитивных типов.

Почему классы-обёртки неизменяемые?

Все классы-обёртки в Java объявлены как final, и их внутренние поля также final. Это означает:

public final class Integer extends Number {
    private final int value;
    
    public Integer(int value) {
        this.value = value;
    }
    // ... методы, но НЕТ setter методов
}

Отсутствие методов-сеттеров и финальность полей гарантируют, что после создания объекта его значение не может быть изменено.

Демонстрация неизменяемости

Integer num = new Integer(42);
// Попытка изменить значение - НЕ ВОЗМОЖНО
num.value = 100; // Ошибка компиляции: value has private access

// Присваивание нового объекта - это не изменение, это новая переменная
Integer num = Integer.valueOf(42);
num = Integer.valueOf(100); // num теперь указывает на новый объект

Важные следствия неизменяемости

Безопасность потоков (Thread Safety): Так как объекты не могут быть изменены, они безопасно использовать в многопоточной среде без синхронизации.

Integer sharedValue = Integer.valueOf(42);
// Безопасно использовать в разных потоках
// Никакой thread synchronization не требуется

Кэширование значений: Возможность агрессивного кэширования. Например, Integer кэширует значения от -128 до 127.

Integer a = Integer.valueOf(128);
Integer b = Integer.valueOf(128);
System.out.println(a == b); // false - разные объекты

Integer c = Integer.valueOf(100);
Integer d = Integer.valueOf(100);
System.out.println(c == d); // true - один и тот же объект из кэша

Использование как ключей в HashMap: Неизменяемые объекты идеальны для использования в качестве ключей, так как их hashCode() не меняется.

Map<Integer, String> map = new HashMap<>();
Integer key = Integer.valueOf(42);
map.put(key, "value");
// key остаётся неизменяемым - он будет найден по одному и тому же хешу
map.get(key); // найдёт значение

Автоупаковка и распаковка

Опасность заблуждения о мутабельности часто возникает при работе с автоупаковкой:

Integer num = 42;
num++; // Это выглядит как изменение, но на самом деле:
       // 1. Распаковка: int value = num.intValue() = 42
       // 2. Инкремент: int newValue = value + 1 = 43
       // 3. Упаковка: num = Integer.valueOf(43)
       // Старый объект не изменился, создан новый!

Хорошая практика

Именно из-за неизменяемости классы-обёртки предпочтительны для использования в:

  • Коллекциях (как ключи или значения)
  • Многопоточных приложениях
  • В качестве полей в других immutable классах
  • Параметров, передаваемых между модулями

Это противоположно изменяемым типам вроде StringBuilder или пользовательских классов без механизма неизменяемости.