Почему это ==, но не 'равняется ()'?

PyCrypto должен быть тем для Вас.

22
задан Eric Wilson 11 August 2009 в 12:31
поделиться

8 ответов

Причина, по которой

X == y

является истинным, связана с продвижением двоичных чисел . Когда хотя бы один операнд оператора равенства может быть преобразован в числовой тип, используется числовой оператор равенства . Сначала распаковывается первый операнд. Затем оба операнда преобразуются в int .

Хотя

X.equals(y)

- это обычный вызов функции. Как уже упоминалось, y будет автоматически упакован в объект Short . Integer.equals всегда возвращает false, если аргумент не является экземпляром Integer . Это можно легко увидеть, проверив реализацию.

Кто-то может возразить, что это недостаток дизайна.

12
ответ дан 29 November 2019 в 04:20
поделиться

(small) Целочисленные экземпляры кэшируются, поэтому инвариант x == y сохраняется для небольших экземпляров (на самом деле -127 +128, зависит от JVM):

Integer a = 10;
Integer b = 10;

assert(a == b); // ok, same instance reused

a = 1024;
b = 1024;

assert(a == b); // fail, not the same instance....
assert(a.equals(b)); // but same _value_

EDIT

4 ) и 5) дают false, потому что равно типов проверки: X - целое число, тогда как Y - короткое. Это метод java.lang.Integer # equals :

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }

    return false;
}
22
ответ дан 29 November 2019 в 04:20
поделиться

Боевой дух истории:

Автобокс / распаковка сбивает с толку, как и продвижение типов. Вместе они дают хорошие загадки, но ужасающий код.

На практике редко имеет смысл использовать числовые типы меньше int, и я почти склонен настраивать свой компилятор eclipse, чтобы отмечать все автобоксирование и распаковку как ошибку .

7
ответ дан 29 November 2019 в 04:20
поделиться

Ваша проблема здесь не только в том, как он обрабатывает ==, но и в автобоксировании ... Когда вы сравниваете Y и 9, вы сравниваете два равных примитива, в последних двух случаях вы просто получаете false потому что так работают равные. Два объекта равны, только если они одного вида и имеют одинаковую ценность. Когда вы говорите в «X.equals (y)», вы говорите ему выполнить Integer.equals (Short), и, глядя на реализацию Integer.equals (), он завершится ошибкой:

   public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
    }

Из-за автобокса последние два приведут к в том же случае неудачи, поскольку они оба будут переданы как Шорты.

Edit: Забыл одну вещь ... В случае results.add (X == y); он распакует X и выполнит (X.intValue () == y), что оказывается истинным, а также 9 == 9

3
ответ дан 29 November 2019 в 04:20
поделиться

Это автоматическое преобразование называется автобоксингом.

1
ответ дан 29 November 2019 в 04:20
поделиться

Java при необходимости автоматически преобразует целое число в целое. То же самое и с Шорт. Эта функция называется autoboxing и autounboxing. Вы можете прочитать об этом здесь .

Это означает, что при запуске кода:

int a = 5;
Integer b = a;
System.out.println(a == b);

Java преобразует его в:

int a = 5;
Integer b = new Integer(a);
System.out.println(a == b.valueOf());
1
ответ дан 29 November 2019 в 04:20
поделиться

Я помню, что хорошей практикой для переопределения "equal (object obj)" является сначала проверка типа переданного параметра. Так что, возможно, это вызывает X .equals (Y) должно быть ложным . Вы можете проверить исходный код, чтобы узнать правду :)

1
ответ дан 29 November 2019 в 04:20
поделиться

Немного подробнее о том, как работает автобоксинг и как кэшируются "маленькие" целочисленные объекты с "маленькими" значениями:

Когда примитивное целое число автоматически преобразуется в целое число, компилятор делает это путем замены кода с вызовом Integer.valueOf (...). Итак, следующее:

Integer a = 10;

заменяется компилятором следующим:

Integer a = Integer.valueOf(10);

Метод valueOf (...) класса Integer поддерживает кэш, содержащий объекты Integer для всех значений от -127 до 128. Если вы вызываете valueOf (...) со значением, находящимся в этом диапазоне, метод возвращает уже существующий объект из кеша. Если значение находится за пределами диапазона, он возвращает новый объект Integer, инициализированный указанным значением. (Если вы хотите точно знать, как это работает, найдите файл src.zip в каталоге установки JDK и найдите исходный код класса java.

1
ответ дан 29 November 2019 в 04:20
поделиться
Другие вопросы по тегам:

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