Гарантируется что новое Целое число (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": мы используем == ссылочное сравнение идентификационных данных и a new объект никогда не будет == к уже существующему объекту.

Вопрос о первых 3 строках: те сравнения, которые, как гарантируют, будут на примитиве int, с Integer автораспакованный? Есть ли случаи, где примитив был бы автоупакован вместо этого, и ссылочные сравнения идентификационных данных выполняются? (который все затем был бы false!)

25
задан polygenelubricants 14 May 2010 в 05:06
поделиться

2 ответа

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

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

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

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

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

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

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

Если операнды оператора равенства оба относятся к любой ссылке { {1}} или нулевой тип, тогда операция - это равенство объектов

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

20
ответ дан 28 November 2019 в 21:45
поделиться

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

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

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

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

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

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

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

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

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

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

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

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

Это выводит true , потому что:

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

Резюме

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

Ссылки

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

7
ответ дан 28 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

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