a == b гарантированно даст true: литерал 127 попадает в гарантированный JLS диапазон boxing. Для c == d с числом 128 результат не гарантирован: обычно false при кэше до 127, но может быть true при расширенном кэшировании. Здесь == сравнивает ссылки. a.equals(b) и c.equals(d) оба дадут true.
Что выведет сравнение Integer через == для значений 127 и 128?
Разбор исходного Java-кода: автопакование, гарантированный диапазон кэша, сравнение ссылок и сравнение числовых значений.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Вопрос относится к следующей программе:
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. Вывод задачи — не строить логику сравнения чисел на случайном совпадении объектов из кэша.