Integer a1 = 123; Integer a2 = 123; boolean result = a1 == a2;
Наивно полагая, что я неплохо знаю основы языка, я конечно же ответил false.
Оказалось что во первых: "а вот и нифига не правильно (т.е. result == true)", a во вторых: "такой ответ не всегда такой".
Итак:
Integer это самый обычный класс, и из 'общей картины' выделяется только тем, что для него работает автобоксинг.
И по этому в выражении a1==a2 сравниваются не сами числа (в нашем случае 123), а объектные ссылки.
И по этому объектные ссылки в нашем примере должны быть разные.
НО! result==true!?
Как оказалось есть еще 2 момента:
Автобоксинг эквивалентен вызовом Integer.valueOf(int).
Объекты (instances) для чисел от -128 до 127 кешируются.
Поэтому в случае:
Integer a1 = 123; Integer a2 = 123; boolean result = a1 == a2;мы имеем 2 ссылки на один и тот же объект и result==true.
А вот в случае:
Integer a1 = 1234; Integer a2 = 1234; boolean result = a1 == a2;получаем 2 разных объекта и result==false.
Выводы:
1. Детали можно узнаь просмотрев реализацию java.lang.Integer.valueOf(int).
2. Подобное кеширование реализовано для всех целочисленных оберточных типов.
3. Подобный механизм кеширования используется для java.math.BigBecimal. Кешируются нули (т.е. варианты значений 0).
4. +1 к моему списку трюков мира Java.
И в завершение:
public class IntegerCachingTest { public static final int LESS_TAHAN_127 = 100; public static final int MORE_TAHAN_127 = 1000; @Test public void testAutoboxing_LessThan127() { Integer a1 = LESS_TAHAN_127; Integer a2 = LESS_TAHAN_127; assertSame(a1, a2); } @Test public void testAutoboxing_MoreThan127() { Integer a1 = MORE_TAHAN_127; Integer a2 = MORE_TAHAN_127; assertNotSame(a1, a2); } @Test public void testInstantiation_LessThan127() { Integer a1 = new Integer(LESS_TAHAN_127); Integer a2 = new Integer(LESS_TAHAN_127); assertNotSame(a1, a2); } @Test public void testInstantiation_MoreThan127() { Integer a1 = new Integer(MORE_TAHAN_127); Integer a2 = new Integer(MORE_TAHAN_127); assertNotSame(a1, a2); } @Test public void testValueOf_LessThan127() { Integer a1 = Integer.valueOf(LESS_TAHAN_127); Integer a2 = Integer.valueOf(LESS_TAHAN_127); assertSame(a1, a2); } @Test public void testValueOf_MoreThan127() { Integer a1 = Integer.valueOf(MORE_TAHAN_127); Integer a2 = Integer.valueOf(MORE_TAHAN_127); assertNotSame(a1, a2); } }
Комментариев нет:
Отправить комментарий