Гарантируется ли, что новое целое число (i) == i в Java? - PullRequest
25 голосов
/ 14 мая 2010

Рассмотрим следующий фрагмент:

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"

Очевидно, что последняя строка будет ВСЕГДА печатать "false": мы используем == сравнение идентификаторов ссылок, а new объект будет НИКОГДА не будет == к уже существующему объекту.

Вопрос касается первых 3 строк: гарантируется ли те сравнения *1017* на примитиве int при автоматическом распаковывании Integer? Существуют ли случаи, когда примитив вместо этого будет автоматически упакован, и будет проведено сравнение эталонных идентификаторов? (что все тогда будет false!)

Ответы [ 2 ]

20 голосов
/ 14 мая 2010

Да. JLS §5.6.2 определяет правила для двоичного числового продвижения. Частично:

Когда оператор применяет двоичный файл числовое продвижение на пару операнды, каждый из которых должен обозначать значение, которое можно преобразовать в числовое значение типа, применяются следующие правила, в заказ с использованием расширяющегося преобразования (§5.1.2) для преобразования операндов как необходимо:

Если какой-либо из операндов имеет ссылочный тип, распаковка конверсии (§5.1.8) выполняется.

Двоичное числовое продвижение применяется для нескольких числовых операторов, включая «операторы числового равенства == и! =.»

JLS §15.21.1 (Операторы числового равенства == и! =) Указывает:

Если операнды равенства оператор оба имеют числовой тип, или один числового типа, а другой конвертируемое (§5.1.8) в числовое тип, двоичное числовое продвижение исполняется с операндами (§5.6.2).

В отличие от этого JLS §15.21.3 (операторы справочного равенства == и! =) Обеспечивают:

Если операнды равенства оператор оба из ссылки тип или нулевой тип, то операция равенство объектов

Это соответствует общему пониманию бокса и распаковки, это делается только при несоответствии.

7 голосов
/ 14 мая 2010

Сначала я объясню точно, когда == является ссылочным равенством, а точно, когда это числовое равенство. Условия для референтного равенства проще, поэтому сначала он будет объяснен.

JLS 15.21.3 равенство ссылок Операторы == и !=

Если операнды оператора равенства имеют либо ссылочный тип, либо null , то операция является объектным равенством.

Это объясняет следующее:

System.out.println(new Integer(0) == new Integer(0)); // "false"

Оба операнда Integer, которые являются ссылочными типами, и поэтому == является сравнением равенства ссылок, и два объекта new никогда не будут == друг для друга, поэтому он печатает false.

Чтобы == было числовым равенством, хотя бы один из операндов должен иметь числовой тип ; это указывается следующим образом:

JLS 15.21.1 Операторы числового равенства == и !=

Если операнды оператора равенства оба числового типа, или один равен числового типа, а другой преобразуется в числовой тип, двоичный тип числовое продвижение выполняется по операндам. Если повышенный тип операндов - int или long, то выполняется проверка на целочисленное равенство; если повышенный тип равен float or double`, то выполняется тест на равенство с плавающей точкой.

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

Итак, рассмотрим следующее:

System.out.println(new Integer(0) == 0); // "true"

Это печатает true, потому что:

  • правый операнд является числовым int типом
  • левый операнд можно преобразовать в числовой тип, распаковав в int
  • следовательно == является операцией числового равенства

Резюме

  • Если оба операнда == и != являются ссылочными типами, это всегда будет операция равенства ссылок
    • Неважно, можно ли преобразовать операнды в числовые типы
  • Если хотя бы один из операндов является числовым типом, это всегда будет операция числового равенства
    • При необходимости будет выполнена автоматическая распаковка одного (не более!) Операнда

Ссылки

Смежные вопросы

...