Что выведет сравнение Integer через == для значений 127 и 128?

Разбор исходного Java-кода: автопакование, гарантированный диапазон кэша, сравнение ссылок и сравнение числовых значений.

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

Что ответить на собеседовании

a == b гарантированно даст true: литерал 127 попадает в гарантированный JLS диапазон boxing. Для c == d с числом 128 результат не гарантирован: обычно false при кэше до 127, но может быть true при расширенном кэшировании. Здесь == сравнивает ссылки. a.equals(b) и c.equals(d) оба дадут true.

Подробный разбор

Ответ с пояснениями

Вопрос относится к следующей программе:

public class Main {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        Integer c = 128;
        Integer d = 128;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}

Первая строка вывода — true. Вторая обычно оказывается false, если реализация использует кэш Integer с верхней границей 127, но без сведений о реализации и настройках утверждать это безусловно нельзя.

Присваивание целочисленного литерала переменной типа Integer выполняет boxing: примитивное значение превращается в ссылку на объект-обёртку. Оператор == между двумя Integer проверяет идентичность ссылок, а не равенство хранимых чисел. Само равенство значений не заставляет этот оператор вызывать equals.

Для boxing константных целочисленных выражений от −128 до 127 включительно JLS гарантирует совпадение ссылок при одинаковом значении. Поэтому a == b в данном коде обязано быть true. Для 128 такой гарантии нет: допустимы как разные объекты, так и повторное использование одного. JLS: boxing conversion.

Контракт Integer.valueOf(int) также прямо разрешает кэшировать значения за пределами обязательного диапазона. Расширенное кэширование может сделать c == d истинным; оно не меняет сами числа. Integer.valueOf.

Для сравнения значений в этом примере используйте:

System.out.println(a.equals(b)); // true
System.out.println(c.equals(d)); // true

Integer.equals проверяет тип и числовое значение. Если возможен null, сначала учитывают его отдельно либо применяют null-safe сравнение. При сравнении Integer с примитивным int правила уже другие: происходит unboxing, который для null вызывает NullPointerException. Вывод задачи — не строить логику сравнения чисел на случайном совпадении объектов из кэша.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку