Почему целые числа не кэшируются в Java? - PullRequest
25 голосов
/ 11 марта 2011

Я знаю, что похожих сообщений по этой теме, но они не совсем отвечают на мой вопрос.Когда вы делаете:

Integer a = 10;
Integer b = 10;
System.out.println("a == b: " + (a == b));

Это (по-видимому) будет печатать true большую часть времени, потому что целые числа в диапазоне [-128, 127] так или иначе кэшируются.Но:

Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println("a == b: " + (a == b));

Вернется false.Я понимаю, что я запрашиваю новые экземпляры Integer, но так как примитивы в штучной упаковке являются неизменяемыми в Java, и механизм уже существует, чтобы делать "правильные вещи" (как видно в первом случае), почему это происходит?

Разве не имеет смысла, если все экземпляры целого числа с 10 будут одним и тем же объектом в памяти?Другими словами, почему у нас нет «Integer interning», которое было бы похоже на «String interning»?

Еще лучше, разве не имело бы больше смысла, если бы примитивы в штучной упаковке представляли то же самое? независимо от значения (и типа) , один и тот же объект?Или хотя бы правильно ответьте на ==?

Ответы [ 15 ]

1 голос
/ 11 марта 2011

Новый экземпляр - это новый экземпляр, поэтому они равны по значению, но они не равны как объекты.

Так что a == b не может вернуть true.

Если бы это был 1 объект, как вы просите: a+=2; добавит 2 ко всем int = 10 - это было бы ужасно.

0 голосов
/ 13 мая 2015

Обратите также внимание, что диапазон кэша в Java 1.5 был от -128 до 127, но в Java 1.6 и далее он является диапазоном по умолчанию, т. Е. Вы можете установить верхнее значение> = 127, передав -XX: AutoBoxCacheMax = new_limit из командной строки

0 голосов
/ 11 марта 2011

Если вы точно описываете поведение своего кода, это звучит так, будто автобокс не работает в операторе 'gets' (=), а звучит как Integer x = 10; дает объекту xa указатель памяти '10' вместо значения 10. Поэтому ((a == b) == true) (будет иметь значение true, потому что == для объектов работает с адресами памяти, которые вы присвоили обоим 10 .

Так, когда вы должны использовать автобокс и распаковку? Используйте их только тогда, когда существует «несоответствие импеданса» между ссылочными типами и примитивами, например, когда вам нужно поместить числовые значения в коллекцию. Не рекомендуется использовать автобокс и распаковку для научных вычислений или другой чувствительный к производительности числовой код. Integer не является заменой для int; Автобокс и распаковка стирают различие между примитивными типами и ссылочными типами, но они не устраняют его.

Что оракул может сказать по этому вопросу.

Обратите внимание, что в документации нет примеров с оператором '='.

0 голосов
/ 11 марта 2011

Это потому, что вы используете оператор new для создания объектов.

Integer a = Integer.valueOf(10);
Integer b = Integer.valueOf(10);
System.out.println("a == b: " + (a == b));

Это выведет true.Странно, но Java.

0 голосов
/ 11 марта 2011

Для Integer объектов используйте для сравнения условие a.equals(b).

Компилятор не будет выполнять за вас распаковку во время сравнения, если вы не назначите значение базовому типу.

...