Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

Обёртки примитивов в Java: boxing, unboxing и null

💻 Информатика · 10 класс

Integer вместо int, автоматические преобразования и безопасное сравнение значений.

Клавиатура в компьютерном классе
Иллюстрация к предмету «Информатика»Hmartil · Wikimedia Commons · CC BY-SA 4.0

Зачем существуют классы-обёртки

В Java int, double, boolean и другие примитивы не являются объектами. Для них предусмотрены соответствующие ссылочные типы: Integer, Double, Boolean, а также Byte, Short, Long, Float и Character. Они нужны, например, в обобщённых коллекциях: List<Integer> допустим, List<int> — нет. Массив int[] при этом является объектом, хотя его элементы — примитивы.

Два направления преобразования

Boxing преобразует примитивное значение в обёртку; unboxing извлекает примитив. Компилятор может вставить такие преобразования автоматически:

Integer stored = 7;   // boxing
int value = stored;   // unboxing
System.out.println(value + 1);

Результат — 8. При сложении нужно числовое значение, поэтому обёртка распаковывается. Для явного получения Integer обычно используют Integer.valueOf(7), а не устаревший конструктор new Integer(7).

Разобранный пример с null

Integer missing = null;
int number = missing;

Вторая строка вызывает NullPointerException: у null невозможно извлечь значение int. Ошибка не означает, что int умеет хранить null. Проблема возникла раньше — при автоматической распаковке ссылочного значения.

Если отсутствие числа допустимо, нужно явно определить поведение. Например:

Integer savedScore = null;
int score = savedScore == null ? 0 : savedScore;

Получится 0, поскольку выбранная ветвь не распаковывает null. Но ноль — решение автора программы, а не универсальное значение «нет данных». В другой задаче правильнее сообщить об отсутствии результата, чтобы не спутать его с настоящим нулевым баллом.

Почему == ненадёжен для сравнения обёрток

Когда оба операнда ссылочные, == проверяет тождество объектов, а не просто числовое равенство. Для части малых значений используются общие объекты; из-за этого случайный тест может создать ложную уверенность. Для значений применяют equals, а с возможным null — Objects.equals(a, b). Сравнение Integer с int может включать распаковку и снова требует внимания к null.

Практика

  1. Что выведет Integer x = 12; int y = x; затем println(y * 2)?
  2. Почему List<Integer> может содержать null, а переменная int — нет?
  3. Как сравнить два Integer a и b по значениям, если один из них может отсутствовать?

Ответы

1. 24: значение 12 упаковано, затем распаковано и умножено на 2. 2. Integer — ссылочный тип, для которого возможен null; int представляет примитивное целое число. Допустимость null в конкретной коллекции зависит ещё и от её реализации. 3. Objects.equals(a, b); вызов a.equals(b) небезопасен при a == null.

Частые ошибки

Не используйте null как «особое число» без проверки перед арифметикой. Не доказывайте корректность == одним примером с маленькими числами. И не выбирайте обёртки повсюду автоматически: примитив и объект имеют разные задачи и стоимость представления.

Связанные материалы

Источники и материалы