Сравнение класса-оболочки с примитивом с помощью 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 является целым, оно приводит к ложному. Надеюсь, это поможет вам.

Ответ 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