Я просто видел код, подобный этому:
public class Scratch
{
public static void main(String[] args)
{
Integer a = 1000, b = 1000;
System.out.println(a == b);
Integer c = 100, d = 100;
System.out.println(c == d);
}
}
Когда работал, этот блок кода распечатает:
false
true
Я понимаю, почему первое false
: потому что два объекта являются отдельными объектами, таким образом, ==
сравнивает ссылки. Но я не могу выяснить, почему второй оператор возвращается true
? Есть ли некоторое странное правило автоупаковки, которое умирает, когда значение Целого числа находится в определенном диапазоне? Что продолжается здесь?
Строка true
фактически гарантируется спецификацией языка. Из раздела 5.1.7 :
Если упаковываемое значение p истинно, ложь, байт, символ в диапазоне \ u0000 в \ u007f, или int, или short число от -128 до 127, тогда пусть r1 и r2 - результат любых двух бокс конвертации п. Это всегда случай, когда r1 == r2.
Обсуждение продолжается, предполагая, что, хотя ваша вторая строка вывода гарантирована, первая - нет (см. Последний абзац, цитируемый ниже):
В идеале, упаковка данного примитива значение p, всегда будет давать идентичная ссылка. На практике это может оказаться невозможным при использовании существующих методы реализации. Правила выше - прагматический компромисс. В последнее предложение выше требует, чтобы определенные общие значения всегда помещаются в рамку в неразличимые объекты. В реализация может кэшировать их лениво или нетерпеливо.
Для других значений эта формулировка запрещает любые предположения о идентичность упакованных значений на часть программиста. Это позволило бы (но не требуют) совместного использования некоторых или все эти ссылки.
Это гарантирует, что в большинстве случаев случаях поведение будет желанный, не навязывая неуместного снижение производительности, особенно на небольшие устройства. Менее ограниченный объем памяти реализации могут, например, кешировать все персонажи и шорты, как а также целые и длинные числа в диапазон от -32К до + 32К.
Целочисленные объекты в некотором диапазоне (я думаю, может быть от -128 до 127) кэшируются и используются повторно. Целые числа вне этого диапазона каждый раз получают новый объект.
Да, есть странное правило автобокса, которое срабатывает, когда значения находятся в определенном диапазоне. Когда вы назначаете константу переменной Object, ничто в определении языка не говорит, что новый объект должен быть создан . Он может повторно использовать существующий объект из кеша.
Фактически, JVM обычно хранит для этой цели кеш небольших целых чисел, а также такие значения, как Boolean.TRUE и Boolean.FALSE.
Я предполагаю, что Java хранит кеш небольших целых чисел, которые уже «упакованы», потому что они очень распространены, и это экономит чертовски много времени, чтобы повторно использовать существующий объект. чем создать новый.
В Java бокс работает в диапазоне от -128 до 127 для целого числа. Когда вы используете числа в этом диапазоне, вы можете сравнить его с оператором ==. Для целочисленных объектов за пределами диапазона вы должны использовать equals.