Вопрос

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

    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 линиях: это сравнения гарантировано быть на примитиве int, с Integer Auto-Unboxed? Есть ли случаи, когда примитив будет автоматически в штучной упаковке, и выполняются ссылочные сравнения личности? (что бы все тогда было false!)

Это было полезно?

Решение

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

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

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

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

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

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

В противоположность, JLS §15.21.3 (Операторы ссылочного равенства == и! =) Предусматривает:

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

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Это отпечатки true, так как:

  • правильный операнд является численность int тип
  • левый операнд является конвертируемым числовой тип, распадающийся в int
  • поэтому == является операцией численного равенства

Резюме

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

Рекомендации

Связанные вопросы

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top