默认情况下,Java对基元执行Binary Numeric Promotion,但不对对象执行相同的操作。这是一个快速测试来证明:
public static void main(String... args) {
if(100 == 100L) System.out.println("first trial happened");
if(Integer.valueOf(100).equals(Long.valueOf(100))) {
System.out.println("second trial was true");
} else {
System.out.println("second trial was false");
}
if(100D == 100L) System.out.println("third trial, fun with doubles");
}
输出:
first trial happened
second trial was false
third trial, fun with doubles
这显然是 正确行为 - Integer
不 a Long
。但是,Number
子类是否存在“值等于”,它会以100 == 100L
返回true的方式返回true?还是100d == 100L
?换句话说,是否有一个方法(不是Object.equals
)将对象的二进制数字促销行为等效?
答案 0 :(得分:3)
此
if(100 == 100L) System.out.println("first trial happened");
否则,如果任一操作数的类型为long,则转换另一个操作数 很久。
因此100L == 100L
这个
if(Integer.valueOf(100).equals(Long.valueOf(100))) {
System.out.println("second trial was true");
} else {
System.out.println("second trial was false");
}
“失败”,因为Integer#equals()
方法检查传递的对象是否为instanceof
Integer
。如果不是,则立即返回false
。
此
if(100d == 100l) System.out.println("third trial, fun with doubles");
与第一个相同,但double
代替long
。
盒装类型的所有equals()
方法都会检查instanceof
各自的类型,因此无法使它们正常工作。
你可能不喜欢这个解决方案,但它会有类似的东西
if (Integer.valueOf(100).intValue() == Long.valueOf(100).longValue()) {
System.out.println("second trial was true");
} else {
System.out.println("second trial was false");
}
答案 1 :(得分:2)
Guava提供了一些很好的实用工具来处理基元,包括每种类型的compare()方法:
int compare(prim a, prim b)
事实上,从Java 7开始,JDK已经添加了相同的功能。这些方法不提供任意Number
比较,但是它们可以为您提供定义任何类型安全比较的粒度。 d,通过选择要使用的类(Longs
,Doubles
等)。
@Test
public void valueEquals() {
// Your examples:
assertTrue(100 == 100l);
assertTrue(100d == 100l);
assertNotEquals(100, 100l); // assertEquals autoboxes primitives
assertNotEquals(new Integer(100), new Long(100));
// Guava
assertTrue(Longs.compare(100, 100l) == 0);
assertTrue(Longs.compare(new Integer(100), new Long(100)) == 0);
assertTrue(Doubles.compare(100d, 100l) == 0);
// Illegal, expected compare(int, int)
//Ints.compare(10, 10l);
// JDK
assertTrue(Long.compare(100, 100l) == 0);
assertTrue(Long.compare(new Integer(100), new Long(100)) == 0);
assertTrue(Double.compare(100d, 100l) == 0);
// Illegal, expected compare(int, int)
//Integer.compare(10, 10l);
// Illegal, expected compareTo(Long) which cannot be autoboxed from int
//new Long(100).compareTo(100);
}
答案 2 :(得分:1)
如果只关心数字值,则应使用compareTo
方法而不是equals
。