使用equals()比较包装类和基元会产生奇怪的行为

时间:2015-02-20 07:46:54

标签: java wrapper 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

8 个答案:

答案 0 :(得分:16)

longWrapper.equals(0)会返回false,因为0会自动退回到Integer,而不是Long。由于这两种类型不同,.equals()会返回false

与此同时,longWrapper == 0true,因为longwrapper值已取消装箱至00 == 0未考虑实际原始类型。< / p>

答案 1 :(得分:4)

因为0不是很长 - 它是一个int,包装器不会将整数转换为Long's

答案 2 :(得分:2)

比较0 == 0L时,您将int字面值与long字面值进行比较。 int获取promotedlong,然后比较它们的值。由于两者都是零,因此结果为true

当您在混音中添加自动装箱时,情况略有不同。基元始终自动装箱到其包装类型。在这里,0是一个int文字,自动装箱到java.lang.Integer包装器实例。由于java.lang.Longjava.lang.Integer是不同的类,因此equals之间必须返回false

答案 3 :(得分:2)

System.out.println(0L == 0)True

所以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。

答案 4 :(得分:1)

这一个:

System.out.println(longWrapper == 0);

==进行比较,因此它会将您的Long取消装箱,并且您正在比较两个基元,两者都是零。

这一个:

System.out.println(longWrapper.equals(0));

equals进行比较,因此它将(int)零作为Integer加载。 Long对象永远不会等于Integer对象,即使它们保持相同的数字。

答案 5 :(得分:0)

我认为这是因为equals方法中的0是一个整数。将longPrimitive定义为0时,此0将转换为long值。 equals方法接受所有对象,因此0保持整数并且不被转换。我的猜测是,在equals方法中,如果给定对象是long的实例,则会有一个调用,因为这个0是一个Integer,所以它会导致false。 我希望这可以帮助你

答案 6 :(得分:0)

Long的equals方法解释了为什么

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)会将pameter装入Long

答案 7 :(得分:0)

来自Long.java课程:

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

因此,当您使用等号将Longint进行比较时,if条件会失败,并且该方法会返回false

由于autoboxing and unboxing

,其他方法会返回true