2010-05-21 48 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