В чем разница в производительности между примитивным типом и его классом-оберткой в Java?

«В чем разница в производительности между примитивным типом и его классом-оберткой в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Использование примитивных типов (int, long, boolean) значительно эффективнее, чем их классов-оберток (Integer, Long, Boolean), по нескольким причинам:

Критерий Примитивный тип (например, int) Класс-обертка (например, Integer)
Хранение В стеке (stack memory). В куче (heap memory).
Память 4 байта. ~16 байт (заголовок объекта + ссылка).
Операции Прямые арифметические операции. Требуют автоупаковки/распаковки (autoboxing/unboxing), создающей временные объекты.
Сравнение == сравнивает значения. == сравнивает ссылки; для значений нужно использовать .equals() или == после unboxing.

Практический пример разницы в производительности:

// Быстро: операции только с примитивами в стеке
long sumPrimitive = 0L;
for (int i = 0; i < 1_000_000; i++) {
    sumPrimitive += i; // Простое сложение
}

// Медленно: накладные расходы на автоупаковку и сборку мусора
Long sumWrapper = 0L; // Неявная упаковка long -> Long
for (int i = 0; i < 1_000_000; i++) {
    sumWrapper += i; // Каждая итерация: i упаковывается в Integer, затем в Long
}

Второй цикл может работать в 5-10 раз медленнее из-за создания миллионов временных объектов Long и нагрузки на Garbage Collector.

Рекомендация: Используйте классы-обертки только когда это необходимо (например, для хранения в коллекциях List<Integer>, работы с дженериками или представления null-значений).