Странная Целочисленная упаковка в Java

Я просто видел код, подобный этому:

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? Есть ли некоторое странное правило автоупаковки, которое умирает, когда значение Целого числа находится в определенном диапазоне? Что продолжается здесь?

106
задан Tom 24 May 2015 в 12:12
поделиться

5 ответов

Строка true фактически гарантируется спецификацией языка. Из раздела 5.1.7 :

Если упаковываемое значение p истинно, ложь, байт, символ в диапазоне \ u0000 в \ u007f, или int, или short число от -128 до 127, тогда пусть r1 и r2 - результат любых двух бокс конвертации п. Это всегда случай, когда r1 == r2.

Обсуждение продолжается, предполагая, что, хотя ваша вторая строка вывода гарантирована, первая - нет (см. Последний абзац, цитируемый ниже):

В идеале, упаковка данного примитива значение p, всегда будет давать идентичная ссылка. На практике это может оказаться невозможным при использовании существующих методы реализации. Правила выше - прагматический компромисс. В последнее предложение выше требует, чтобы определенные общие значения всегда помещаются в рамку в неразличимые объекты. В реализация может кэшировать их лениво или нетерпеливо.

Для других значений эта формулировка запрещает любые предположения о идентичность упакованных значений на часть программиста. Это позволило бы (но не требуют) совместного использования некоторых или все эти ссылки.

Это гарантирует, что в большинстве случаев случаях поведение будет желанный, не навязывая неуместного снижение производительности, особенно на небольшие устройства. Менее ограниченный объем памяти реализации могут, например, кешировать все персонажи и шорты, как а также целые и длинные числа в диапазон от -32К до + 32К.

97
ответ дан 24 November 2019 в 03:52
поделиться

Целочисленные объекты в некотором диапазоне (я думаю, может быть от -128 до 127) кэшируются и используются повторно. Целые числа вне этого диапазона каждый раз получают новый объект.

8
ответ дан 24 November 2019 в 03:52
поделиться

Да, есть странное правило автобокса, которое срабатывает, когда значения находятся в определенном диапазоне. Когда вы назначаете константу переменной Object, ничто в определении языка не говорит, что новый объект должен быть создан . Он может повторно использовать существующий объект из кеша.

Фактически, JVM обычно хранит для этой цели кеш небольших целых чисел, а также такие значения, как Boolean.TRUE и Boolean.FALSE.

5
ответ дан 24 November 2019 в 03:52
поделиться

Я предполагаю, что Java хранит кеш небольших целых чисел, которые уже «упакованы», потому что они очень распространены, и это экономит чертовски много времени, чтобы повторно использовать существующий объект. чем создать новый.

4
ответ дан 24 November 2019 в 03:52
поделиться

В Java бокс работает в диапазоне от -128 до 127 для целого числа. Когда вы используете числа в этом диапазоне, вы можете сравнить его с оператором ==. Для целочисленных объектов за пределами диапазона вы должны использовать equals.

3
ответ дан 24 November 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: