Вопрос с собеседования · Java

Почему int v = flag ? map.get(key) : 0 (map.get может вернуть null) способно бросить NPE?

MiddleОсновы языка
Коротко

Если одна ветвь тернарного оператора int, а другая Integer, тип всего выражения — int: обёрточная ветвь распаковывается, и null даёт NPE, хотя код выглядит безопасным.

  • Исправление: привести обе ветви к Integer — flag ? map.get(key) : Integer.valueOf(0)
  • Или map.getOrDefault(key, 0)
  • Правило числового продвижения из спецификации языка

А ещё Та же ловушка с Long и long, Boolean и boolean

Попробуйте сами

Песочница: == против equals и кэш Integer

Подробно

Когда одна ветвь тернарного оператора примитив (int), а другая обёртка (Integer), к выражению применяется числовое расширение и его тип становится int — значит, обёрточная ветвь будет распакована через intValue(). Если выбрана именно она и значение null, получаем NPE, хотя код выглядит безопасным. Лечится тем, что не смешивают обёртку и примитив в одном тернарнике: сначала достают значение с дефолтом (getOrDefault(key, 0)), а уже потом используют.

Что хотят услышать

  • Тип выражения и распаковка.
  • Как исправить.

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

  • Думать, что тернарник вычисляет обе ветви (он вычисляет только выбранную).
  • Смешивать Integer и int в ветвях одного тернарного выражения.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Тип тернарника становится int, и ветка Integer распаковывается — null даёт NPE
  • ✗Тернарный оператор вычисляет обе ветви, поэтому map.get(key) падает всегда
  • ✗map.get(key) при отсутствии ключа сам бросает NPE
  • ✗0 неявно приводится к Integer, и сравнение с null падает

Что спросят дальше

  • Как переписать выражение, чтобы NPE стал невозможен?
  • Почему Object o = cond ? 1 : 2.0 даёт 1.0, а не 1?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования