2010-05-21 46 views
23

有人能告诉我为什么assertSame()在使用大于127的值时会失败吗?JUnit - assertSame

 import static org.junit.Assert.*; 

     ... 

     @Test 
     public void StationTest1() { 
      .. 

      assertSame(4, 4);   // OK 
      assertSame(10, 10);  // OK 
      assertSame(100, 100);  // OK 
      assertSame(127, 127);  // OK 
      assertSame(128, 128);   // raises an junit.framework.AssertionFailedError! 
      assertSame(((int) 128),((int) 128)); // also junit.framework.AssertionFailedError! 
     } 

我正在使用JUnit 4.8.1。

+3

您应该使用'assertSame'只用于引用相等检查 - 例如'a == b'。为了平等,你应该使用'assertEquals'。 – 2010-05-21 21:49:57

回答

44

原因是Java的自动装箱。 您使用的方法:

public static void assertSame(Object expected, Object actual) 

它只适用于对象。当您将int s传递给此方法时,Java会自动调用

Integer.valueOf(int i) 

包含这些值。所以投到int没有效果。

对于小于128的值,Java有一个缓存,所以assertSame()Integer对象与自己进行比较。对于大于127的值,Java创建新的实例,因此assertSame()Integer对象与另一个对象进行比较。因为它们不是同一个实例,所以assertSame()方法返回false。

您应该使用方法:

public static void assertEquals(Object expected, Object actual) 

代替。该方法使用Object中的equals()方法。

+0

JVM *必须缓存-128..127是正确的,但是对于超出该范围的值,完全取决于JVM实现它缓存的范围,例如,“内存限制较少的实现可能会更少,缓存所有的char和short值,以及-32K到+ 32K范围内的int和long值。“_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5 .html#jls-5.1.7通过https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127/20948389#20948389 – weston 2017-10-08 01:14:14

12

assertSame需要两个Object参数,因此编译器必须将int文字自动装入Integer

这相当于

assertSame(Integer.valueOf(128), Integer.valueOf(128)); 

现在的值-128到127之间,JVM将缓存的Integer.valueOf的结果,所以你会得到同样Integer对象返回各一次。对于那个范围以外的值,你会得到新的对象。

因此对于assertSame(127, 127),JUnit比较相同的对象,因此它的工作原理。对于assertSame(128, 128),你会得到不同的对象,所以它会失败。

只是另一个要小心自动装箱的原因。

+0

你是对的JVM必须缓存-128..127,但是对于超出该范围的值,完全取决于它所缓存的JVM实现的范围,_“较少的内存受限的实现可能会缓存所有的char和short值,以及在-32K到+ 32K范围内的int和long值。“_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7通过https://stackoverflow.com/a/20948389/360211 – weston 2017-10-08 10:52:33