5

默认情况下,Java对原语进行二进制数字提升,但对对象不做同样的事情。这是一个快速测试来演示:

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

显然是正确行为 - anInteger不是. 但是,是否存在以与返回 true 相同的方式返回 true 的子类的“值等于”?或者?换句话说,是否有一种方法(不是)可以对对象执行相当于二进制数字提升行为的方法?LongNumber100 == 100L100d == 100LObject.equals

4

3 回答 3

3

这个

if(100 == 100L) System.out.println("first trial happened");

你得到一些二进制数字提升

否则,如果任一操作数是 long 类型,则另一个将转换为 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");
}
于 2013-10-16T18:00:17.553 回答
2

Guava提供了几个很好的实用程序来处理原语,包括每种类型的 compare() 方法:

int compare(prim a, prim b)

事实上,从 Java 7 开始,JDK 已经添加了相同的功能。这些方法不提供任意Number比较,但是它们为您提供了定义任何类型安全比较的粒度,方法是选择哪个类 ( 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);
}
于 2013-10-16T20:49:30.220 回答
1

当您只关心数字值时,您应该使用该compareTo方法而不是。equals

于 2013-10-16T17:59:40.950 回答