Java for Beginner
680 subscribers
573 photos
158 videos
12 files
871 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Автоупаковка и автораспаковка типов в Java

Java разделяет примитивные типы (int, boolean, char и др.) и ссылочные типы (в том числе классы-обертки Integer, Boolean, Character и т.д.). Чтобы упростить работу с обертками, Java (начиная с версии 1.5) ввела механизм автоупаковки (autoboxing) и автораспаковки (unboxing) — автоматическое преобразование между примитивами и их объектными аналогами.


Автоупаковка (Autoboxing)

Это автоматическое преобразование примитива в объект соответствующего класса-обертки.

Пример:
Integer x = 5; // int -> Integer автоматически


Java компилятор сам преобразует это в:

Integer x = Integer.valueOf(5);



Автораспаковка (Unboxing)

Обратное преобразование — объект-обертка в примитив.


Пример:
int y = x; // Integer -> int автоматически


На самом деле компилятор превращает это в:
int y = x.intValue();



Как это работает в памяти


До автоупаковки
int x = 10;
Integer y = new Integer(x); // вручную

x — хранится в стеке, занимает 4 байта.
y — объект в куче, содержит поле типа int со значением 10 и дополнительную информацию (например, hashCode, class pointer и т.д.).


С автоупаковкой
Integer z = 10;
Компилятор заменит это на Integer.valueOf(10), что использует кэш оберток от -128 до 127.


Примеры использования
List<Integer> numbers = new ArrayList<>();
numbers.add(10); // int -> Integer (autoboxing)
int n = numbers.get(0); // Integer -> int (unboxing)
Это работает, потому что ArrayList хранит только объекты, а int автоматически упаковывается и распаковывается.



Зачем нужна автоупаковка

Унификация с коллекциями
List<Integer> list = new ArrayList<>();
list.add(42); // без ручного создания new Integer(42)


Удобство синтаксиса


Писать проще и чище:
Integer sum = 0;
for (int i = 0; i < 10; i++) {
sum += i; // автораспаковка и автоупаковка
}


Обратная совместимость
Автоупаковка позволяет использовать новые коллекции с примитивами, не ломая старый код.


Подводные камни

1. NullPointerException
Автораспаковка объекта, равного null, вызывает исключение:
Integer x = null;
int y = x; // NullPointerException


2. Производительность
Автоупаковка создает лишние объекты, особенно в циклах:
Integer sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i; // каждый шаг — распаковка, сложение, упаковка
}


Альтернатива:
int sum = 0; // быстрее и без накладных расходов


3. Сравнение ссылок

Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false


А вот:
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true — значения из кэша


Потому что:
Integer.valueOf(...) кэширует значения от -128 до 127.
== сравнивает ссылки, а не значения.


4. Неявное создание объектов

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

Разбор кэширования (Integer Cache)
Integer x = 127;
Integer y = 127;
System.out.println(x == y); // true

Integer x = 128;
Integer y = 128;
System.out.println(x == y); // false
Причина — кэш для Integer в диапазоне [-128; 127].


Это реализовано внутри Integer.valueOf():
public static Integer valueOf(int i) {
if (i >= -128 && i <= 127)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}



Практические советы

Используйте примитивы, если нет необходимости в объектах (например, в счетчиках, математике).
Избегайте упаковки в горячих циклах, особенно в производительном коде.
Будьте осторожны с null — автораспаковка null всегда приведет к ошибке.
Для сравнения используйте equals(), а не ==.


#Java #для_новичков #beginner #reference_types #Autoboxing #Unboxing