为什么不Integer.valueOf(42).equals(Long.valueOf(42))
?
equals
的实现是否必须是“反身的,对称的,传递的,一致的”
但不必合理吗? :)
答案 0 :(得分:5)
来自Integer.equals()
的文档:
当且仅当参数不是
null
并且是包含与此对象相同的Integer
值的int
对象时,结果才为真。
换句话说,Integer
永远不会将equals()
测试为Long
(或其他任何不是Integer
的内容),无论代表什么值。只需比较原始值,如果这就是你所追求的。
不允许跨类别比较的一个很好的理由是:你会怎么做?假设您决定实施Integer.equals()
来测试另一个对象是否是Number
的实例,并使用other.intValue()
(所有Number
类都支持)比较值。不幸的结果是
Integer.valueOf(42).equals(Long.valueOf(((Integer.MAX_VALUE + 1L) << 1) + 42))
会测试true
,因为Long.intValue()
只是将其值转换为int
和
(int) ((Integer.MAX_VALUE + 1L) << 1) + 42)
评估为42,因为这是低32位的内容。更糟糕的是,如果您对Long.equals()
使用了相同的逻辑(测试了所有Number
对象使用的longValue()
),那么equals()
测试将不再是对称的。
答案 1 :(得分:1)
提醒您Integer
和Long
是原始类型int
和long
的对象包装类。
以下是Integer
中equals
方法的源代码(value
这里是int
原语。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
以下是Long
中equals
方法的源代码(value
这里是long
原语。
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
从源代码开始,equals
方法首先检查传入的obj
是否是相应类的实例。如果不是,则equals
会跳过对原始value
的检查并返回false
。
正如@Ted Hopp建议的那样,Integer
永远不会测试等于Long
(或其他任何不是Integer
)。建议比较原始值。
如果您仍希望在对象包装器设置中执行等效性检查,那么您可能希望扩展Integer(避免溢出)并让Java编译器为您执行一些auto-(un)boxing。有点像...
Long theLong = Long.valueOf(42);
Integer theInteger = Integer.valueOf(42);
Long theIntegerInLong = (long) theInteger;
System.out.println(theLong.equals(theIntegerInLong) ? "Equal" : "Unequal");
答案 2 :(得分:-1)
.equals()用于比较同一继承层次结构中的对象,包括最终的超类Object。虽然类Integer和Long都继承自java.lang.Number,但类Number显然缺少一个比较Number实例值的.equals()方法。 Integer和Long唯一共享的.equals()方法在Object中。对象 - 对象比较方法不会根据数字的值进行评估,因此打印出看似奇怪的结果。
Integer类的文档说: .equals():“当且仅当参数不为null并且是包含与此对象相同的int值的Integer对象时,结果才为真。”它不像对象那样处理Long值。
显然,根据@David_Wallace,其他类层次结构在其超类中实现.equals()。 new ArrayList()。equals(new LinkedList())返回true,并且都从类java.util.AbstractList继承,它有自己的.equals()实现
答案 3 :(得分:-1)
可以在这样的方式中定义包装类之间的相等性测试,即封装相同数值的两个包装器对象将比较相等,而不管底层类型如何。但是,这样做要求要求所有类型的实例可以比较相同才能彼此了解,或者需要定义一种方法,通过该方法,对象可以将自己与尚未发明的其他对象进行比较。采用前一种方法意味着即使新的数字类型能够表示值5,等于5的Integer
也不能报告自己等于也代表5的新类型的实例。方法将允许新对象与值{5}的Integer
进行比较,但需要增加极大的复杂性才能获得相对较少的好处。
例如,假设一个人定义了BigDecimal
和BigRational
类;前者将数字存储为BigInteger
以及十次幂比例因子;后者存储一对BigInteger
值,表示缩减形式的分数。可以指定所有表示有理数的数值应通过将它们转换为BigRational
并比较结果来进行比较。由于每个有理数都具有唯一的表示,因此这种定义的比较方法将表现为等价关系。不幸的是,它会非常缓慢。在大多数情况下,将比较法转换为其他形式会更有意义,但是尝试识别任意类型组合的最佳常见形式将是困难的。简单地说出不同类型的东西就足以让对象被称为“不同的”#34;