Ответ 1
объяснение
Когда вы сравниваете Integer
против int
с ==
, необходимо преобразовать Integer
в int
. Это называется распаковка.
См. JLS§5.1.8:
Если
r
является ссылкой типаInteger
, а затем распаковка преобразования преобразуетr
вr.intValue()
В этот момент вы сравниваете int
против int
. А примитивы не имеют понятия экземпляров, все они относятся к одному значению. Таким образом, результат true
.
Таким образом, фактический код у вас есть
a.intValue() == c
приводя к сравнению 10 == 10
, оба значения int
, больше нет экземпляров Integer
.
Вы можете видеть, что new Integer(...)
действительно создает новые экземпляры, когда вы сравниваете Integer
против Integer
. Вы сделали это в a == b
.
Заметка
Конструктор new Integer(...)
устарел. Вместо этого вы должны использовать Integer#valueOf
, он потенциально быстрее и также использует внутренний кеш. Из документации:
Возвращает экземпляр
Integer
представляющий указанное значение типаint
. Если новый экземпляр Целое не требуется, как правило, этот метод должен использоваться в предпочтении к конструкторуInteger(int)
, так как этот метод может принести значительно лучшее пространство и время производительность за счет кэширования часто запрашиваемых значений. Этот метод всегда-128
значения в диапазоне от-128
до127
включительно и может кэшировать другие значения за пределами этого диапазона.
Кэширование важно отметить здесь, так как оно возвращает ==
снова к истине (для кэшированных значений):
Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
Кэширование гарантировано для значений между -128
и +127
, но может также использоваться для других.
Также обратите внимание, что ваш b
фактически выходит из кэша, так как
Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
Таким образом, бокс проходит через кеш Integer
(см. JLS§5.1.7).