Гарантируется ли, что новое целое число (i) == i в Java?

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

    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 авто-распакованное? Существуют ли случаи, когда примитив вместо этого будет автоматически упакован, и будет проведено сравнение эталонных идентификаторов? (что все тогда будет false!)

2 ответа

Решение

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

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

Если какой-либо из операндов имеет ссылочный тип, выполняется преобразование без ящика (§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 double`, то выполняется тест на равенство с плавающей точкой.

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

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

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

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

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

Резюме

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

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

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

Другие вопросы по тегам