2010-05-21 3 views
23

Kann mir jemand sagen, warum assertSame() fehlschlägt, wenn ich Werte> 127 verwende?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! 
     } 

Ich benutze JUnit 4.8.1.

+3

Sie sollten 'assertSame' nur für Referenzgleichheitsprüfungen verwenden - zum Beispiel' a == b'. Für die Gleichheit sollten Sie 'assertEquals' verwenden. –

Antwort

44

Der Grund ist das Autoboxen von Java. Sie verwenden die Methode:

public static void assertSame(Object expected, Object actual) 

Es nur mit Objekten arbeitet. Wenn Sie int s an diese Methode übergeben, Java ruft automatisch

Integer.valueOf(int i) 

mit diesen Werten. So hat der Cast zu int keinen Effekt.

Werte für weniger als 128 hat eine Java-Cache, so vergleicht das assertSame()Integer Objekt mit mir. Bei Werten größer als 127 erstellt Java neue Instanzen, sodass assertSame() ein Integer Objekt mit einem anderen vergleicht. Da sie nicht dieselbe Instanz sind, gibt die assertSame() Methode false zurück.

public static void assertEquals(Object expected, Object actual) 

statt:

sollten Sie die Methode verwenden. Diese Methode verwendet die Methode equals() von Object.

+0

Sie haben Recht, dass die JVM * den Cache -128..127 * cachen muss, aber für Werte außerhalb dieses Bereichs ist die JVM-Implementierung völlig abhängig davon, welchen Bereich sie zwischenspeichert, \t _ "Weniger speicherbeschränkte Implementierungen könnten z Speichern Sie alle char- und short-Werte sowie int- und long-Werte im Bereich von -32K bis + 32K. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5 .html # jls-5.1.7 über https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127/20948389#20948389 – weston

12

assertSame dauert zwei Object Argumente, und so muss der Compiler Ihre int Literale in Integer autobox.

Dies entspricht

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

nun für Werte zwischen -128 und 127, wird die JVM die Ergebnisse der Integer.valueOf zwischenzuspeichern, so dass Sie die gleiche Integer Objekt zurück jedes Mal bekommen. Für Werte außerhalb dieses Bereichs erhalten Sie neue Objekte zurück.

So für assertSame(127, 127) vergleicht JUnit die gleichen Objekte, daher funktioniert es. Für assertSame(128, 128), erhalten Sie verschiedene Objekte, so dass es fehlschlägt.

Ein weiterer Grund, vorsichtig mit Autoboxen zu sein.

+0

Sie haben Recht dass die JVM den Cache -128..127 zwischenspeichern muss, aber bei Werten außerhalb dieses Bereichs ist das der JVM-Implementierung überlassen, welchen Bereich sie zwischenspeichert. _ "Weniger speicherbeschränkte Implementierungen könnten beispielsweise alle char- und short-Werte zwischenspeichern. sowie int und long Werte im Bereich von -32K bis + 32K. "_ http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 über https://stackoverflow.com/a/20948389/360211 – weston