Сравнение класса-оболочки с примитивом с помощью equals() дает странное поведение
Рассмотрим приведенную ниже привязку кода.
мы используем equals()
для сравнения объектов, которые в действительности эквивалентны или нет?
Здесь оба значения значимо равны, но почему longWrapper.equals(0)
возвращает false
?
И когда я сравнивал оба значения с оператором ==
, он возвращает true
.
Long longWrapper = 0L;
long longPrimitive = 0;
System.out.println(longWrapper == 0L); // true
System.out.println(longWrapper == 0); //true
System.out.println(longWrapper == longPrimitive); //true
System.out.println(longWrapper.equals(0L)); //true
System.out.println(longWrapper.equals(0)); //false
System.out.println(longWrapper.equals(longPrimitive)); //true
Ответы
Ответ 1
longWrapper.equals(0)
возвращает false
, потому что 0
автобоксирован до Integer
, а не Long
. Поскольку эти два типа отличаются, .equals()
возвращает false
.
Тем временем longWrapper == 0
является true
, потому что значение longwrapper
распаковано на 0
и 0 == 0
без учета реальных примитивных типов.
Ответ 2
Его потому, что 0 не длинный - его int, а wrappers не конвертируют Integer в Long
Ответ 3
Когда вы сравниваете 0 == 0L
, вы сравниваете литерал int
с литералом long
. int
получает продвинутый до long
, а затем сравниваются их значения. Поскольку оба являются нулями, результат равен true
.
Когда вы добавляете автобоксинг в микс, все немного отличается. Примитив всегда автобоксирован к его типу обертки. Здесь 0
, который является литералом int
, автобоксирован экземпляру оболочки java.lang.Integer
. Поскольку java.lang.Long
и java.lang.Integer
являются разными классами, equals
между ними должны возвращать false
.
Ответ 4
System.out.println(0L == 0)
True
.
so longWrapper == 0
, который распакован и результат True
.
И в Long.equals
написано как -
781 public boolean More ...equals(Object obj) {
782 if (obj instanceof Long) {
783 return value == ((Long)obj).longValue();
784 }
785 return false;
786 }
поэтому System.out.println(longWrapper.equals(0));
возвращает false, поскольку 0 будет помещаться в Integer
, а if (obj instanceof Long)
- false.
Ответ 5
Этот:
System.out.println(longWrapper == 0);
сравнивается с ==
, поэтому он отключает ваш Long
, и вы сравниваете два примитива, оба из которых равны нулю.
Этот:
System.out.println(longWrapper.equals(0));
сравнивается с equals
, поэтому он присваивает ноль (int
) как Integer
. Объект Long
никогда не равен объекту Integer
, даже если он содержит один и тот же номер.
Ответ 6
Я думаю, что это потому, что метод 0 в методе равно Integer. Когда вы определяете longPrimitive с 0, это 0 вызывается на длительное значение. метод equals принимает все объекты, и из-за этого 0 остается целочисленным и не литым. Я предполагаю, что в методе equals есть вызов, если данный объект является экземпляром long, и поскольку это 0 является целым, оно приводит к ложному.
Надеюсь, это поможет вам.
Ответ 7
Метод equals Long объясняет, почему
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/lang/Long.java#Long.equals%28java.lang.Object%29
Существует строка
if (obj instanceof Long) {
longWrapper.equals(0) параметр будет иметь тип Integer.
С другой стороны, longWrapper.equals(longPrimitive) помещает пампер в Long
Ответ 8
От Long.java
class:
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
Поэтому, сравнивая Long
с int
с помощью equals, условие if
завершается с ошибкой, и метод возвращает false
.
Другие методы возвращают true
из-за autoboxing and unboxing