使用 equals() 将包装器 class 与原语进行比较会产生奇怪的行为
Comparing wrapper class with primitive using equals() gives strange behavior
考虑下面的代码快照。
我们使用 equals()
来比较对象是否有意义?
这里两个值有意义地相等,但为什么 longWrapper.equals(0)
return false
呢?
当我将两个值与 ==
运算符进行比较时,它 returns 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
这是因为 0 不是 long - 它是 int,包装器不会将整数转换为长整数
longWrapper.equals(0)
returns false
,因为 0
被自动装箱到 Integer
,而不是 Long
。由于两种类型不同,.equals()
returns false
.
同时,longWrapper == 0
是true
,因为longwrapper
值被拆箱为0
,而0 == 0
没有考虑实际的基本类型.
我想是因为equals方法中的0是Integer。当你用 0 定义 longPrimitive 时,这个 0 被转换为长值。 equals 方法接受所有对象,因此 0 保持为整数并且不会被强制转换。我的猜测是,如果给定对象是 long 的实例,则在 equals 方法中有一个调用,因为这个 0 是一个 Integer,它会导致 false。
希望对您有所帮助
当您比较 0 == 0L
时,您是在比较 int
文字和 long
文字。 int
得到 promoted 到 long
,然后比较它们的值。由于两者均为零,因此结果为 true
.
当您将自动装箱添加到组合中时,情况会略有不同。基元总是自动装箱为其包装器类型。在这里,0
,它是一个 int
文字,被自动装箱到一个 java.lang.Integer
包装器实例。由于java.lang.Long
和java.lang.Integer
不同类,equals
之间必须returnfalse
.
这个:
System.out.println(longWrapper == 0);
正在与 ==
进行比较,因此它会拆箱您的 Long
,并且您正在比较两个基元,它们都是零。
这个:
System.out.println(longWrapper.equals(0));
正在与 equals
进行比较,因此它将 (int
) 零作为 Integer
。 Long
对象永远不会等于 Integer
对象,即使它们拥有相同的数字。
Long的equals方法解释了为什么
那里有线
if (obj instanceof Long) {
longWrapper.equals(0) 参数将变为 Integer 类型。
另一方面longWrapper.equals(longPrimitive)会将参数装箱成Long
来自 Long.java
class:
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
因此,当您使用等号比较 Long
与 int
时,if
条件失败并且方法 returns false
.
其他方法return true
由于autoboxing and unboxing
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));
return false 因为 0 将装在 Integer
中并且 if (obj instanceof Long)
是 false。
考虑下面的代码快照。
我们使用 equals()
来比较对象是否有意义?
这里两个值有意义地相等,但为什么 longWrapper.equals(0)
return false
呢?
当我将两个值与 ==
运算符进行比较时,它 returns 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
这是因为 0 不是 long - 它是 int,包装器不会将整数转换为长整数
longWrapper.equals(0)
returns false
,因为 0
被自动装箱到 Integer
,而不是 Long
。由于两种类型不同,.equals()
returns false
.
同时,longWrapper == 0
是true
,因为longwrapper
值被拆箱为0
,而0 == 0
没有考虑实际的基本类型.
我想是因为equals方法中的0是Integer。当你用 0 定义 longPrimitive 时,这个 0 被转换为长值。 equals 方法接受所有对象,因此 0 保持为整数并且不会被强制转换。我的猜测是,如果给定对象是 long 的实例,则在 equals 方法中有一个调用,因为这个 0 是一个 Integer,它会导致 false。 希望对您有所帮助
当您比较 0 == 0L
时,您是在比较 int
文字和 long
文字。 int
得到 promoted 到 long
,然后比较它们的值。由于两者均为零,因此结果为 true
.
当您将自动装箱添加到组合中时,情况会略有不同。基元总是自动装箱为其包装器类型。在这里,0
,它是一个 int
文字,被自动装箱到一个 java.lang.Integer
包装器实例。由于java.lang.Long
和java.lang.Integer
不同类,equals
之间必须returnfalse
.
这个:
System.out.println(longWrapper == 0);
正在与 ==
进行比较,因此它会拆箱您的 Long
,并且您正在比较两个基元,它们都是零。
这个:
System.out.println(longWrapper.equals(0));
正在与 equals
进行比较,因此它将 (int
) 零作为 Integer
。 Long
对象永远不会等于 Integer
对象,即使它们拥有相同的数字。
Long的equals方法解释了为什么
那里有线
if (obj instanceof Long) {
longWrapper.equals(0) 参数将变为 Integer 类型。
另一方面longWrapper.equals(longPrimitive)会将参数装箱成Long
来自 Long.java
class:
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
因此,当您使用等号比较 Long
与 int
时,if
条件失败并且方法 returns false
.
其他方法return true
由于autoboxing and unboxing
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));
return false 因为 0 将装在 Integer
中并且 if (obj instanceof Long)
是 false。