有没有数字"价值相等"?

dur*_*597 5 java primitive numbers equals

默认情况下,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");
}
Run Code Online (Sandbox Code Playgroud)

输出:

first trial happened
second trial was false
third trial, fun with doubles
Run Code Online (Sandbox Code Playgroud)

这是明显的正确的行为-一个Integer不是一个Long.但是,对于Number子类,是否存在"值等于" ,它将以返回true的相同方式100 == 100L返回true?还是100d == 100L?换句话说,是否有一个方法(不是Object.equals)将对象的二进制数字促销行为等效?

dim*_*414 2

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

int compare(prim a, prim b)
Run Code Online (Sandbox Code Playgroud)

事实上,从 Java 7 开始,相同的功能已添加到 JDK 中。这些方法不提供任意Number比较,但是它们为您提供了粒度来定义您想要的任何类型安全比较,通过选择哪个类 ( LongsDoubles等)来使用。

@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);
}
Run Code Online (Sandbox Code Playgroud)