Кто-то может сказать мне, почему assertSame () действительно перестали работать, когда я использую значения> 127?
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.
Причина в автобоксе Явы. Вы используете метод:
public static void assertSame(Object expected, Object actual)
Он работает только с объектами. Когда вы передаете этому методу int
, Java автоматически вызывает
Integer.valueOf( int i )
с этими значениями. Таким образом, приведение к int
не имеет никакого эффекта.
Для значений меньше 128 Java имеет кеш, поэтому assertSame ()
сравнивает объект Integer
с самим собой. Для значений больше 127 Java создает новые экземпляры, поэтому assertSame ()
сравнивает объект Integer
с другим. Поскольку это не один и тот же экземпляр, метод assertSame ()
возвращает false.
Вместо этого вы должны использовать метод:
public static void assertEquals(Object expected, Object actual)
. В этом методе используется метод equals ()
из Object
.
assertSame
принимает два аргумента Object
, поэтому компилятор должен автоматически упаковать ваши литералы int
в Integer
.
Это эквивалентно
assertSame(Integer.valueOf(128), Integer.valueOf(128));
Теперь для значений от -128 до 127 JVM будет кэшировать результаты Integer.valueOf
, поэтому вы получите тот же объект Integer
обратно. каждый раз. Для значений за пределами этого диапазона вы получите новые объекты.
Итак, для assertSame (127, 127)
JUnit сравнивает одни и те же объекты, поэтому он работает. Для assertSame (128, 128)
вы получаете разные объекты, поэтому он терпит неудачу.
Еще одна причина быть осторожнее с автобоксом.