2013-09-17 3 views
3

Я наткнулся на это в Java (JDK 1.7):Java Integer авто авто-бокс

Integer a = 100; 
    Integer b = 100; 
    Integer c = 1000; 
    Integer d = 1000; 

    System.out.println(a == b); //true 
    System.out.println(c == d); //false 
    System.out.println(new Integer(100) == new Integer(100)); //false 
    System.out.println(new Integer(1000) == new Integer(1000)); //false 

Выход: правда ложные ложные ложные

Почему == Ь оценить истину? Что является причиной этого? Это похоже на интернализацию строк?

+0

Да, это так. Спасибо – enotpolaskun

ответ

6

Это похоже на интернализацию строк?

Да - по существу все целые числа, которые могут вписываться в байты (от -128 до +127), интернированы и, таким образом, имеют один и тот же базовый объект. Более крупных нет, и, следовательно, , вероятно, не используют один и тот же базовый объект (это описано в JLS 5.1.7) - хотя обратите внимание, что в спецификации нет ничего, что предотвращало бы большие целые числа, разделяющие один и тот же базовый объект, если кто-то был чтобы выбрать для реализации VM таким образом.

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

В вашем примере new Integer(100) == new Integer(100) это не так, поскольку вы явно создаете новые целые объекты, аналогично тому, как new String("hi") == new String("hi") оценивает значение false.

Просто повторно итерация - при сравнении целых чисел, как это во всех реальных сценариях, то .equals() следует использовать (или, предпочтительно, по-прежнему, == с примитивными числами, если не хороший случай для использования типа объекта.)

+0

Это не распространенная ошибка, но это хорошая причина для использования родных типов Java для чисел, булевых и т. Д. ... –

1

Это потому, что все маленькие целые кешируются (например, для интернализации строк), поэтому вы получаете один и тот же экземпляр, когда вы их используете.

От the specification:

Если значение р будучи в штучной упаковке является истинным, ложным, байт, или символ в диапазоне \ u0000 к \ u007f, или INT или короткое число между -128 и 127 (включительно), то пусть r1 и r2 - результаты любых двух боксов конверсий p. Всегда бывает, что r1 == r2.

И дополнительные ноты просветить на компромиссе, который был сделан:

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

Это гарантирует, что в большинстве случаев поведение будет желательным, не налагая чрезмерного штрафного штрафа, особенно на небольшие устройства. Менее ограниченные памятью реализации могут, например, для , кэшировать все значения char и short, а также значения int и long в диапазоне от -32K до + 32K.

+0

Спасибо. Насколько малым является целое число? В чем основная причина этого, производительность и память? – enotpolaskun

1

значения от -128 до 127 кэшируются

java.lang.Integer имеет внутренний статический класс, который кэширует все объекты Integer между -128 и 127