Все ответы уже давно написаны
Примерно с такой фразы началась техническая часть одного из моих собеседований. После очередной затяжки электронной сигареты собеседующий прислал ссылку.
В целом, крупный российский биржевой холдинг может себе позволить “лайвкодинг в блокноте”, о котором ведется множество дебатов в последнее время. А вот человек, покуривающий на фоне интернет-мема “Них** не понял, но очень интересно.”, и до этого момента вызывал сугубо желание завершить встречу досрочно. Но работая в компании, которая всем сердцем полюбила аутстаффинг, приходится в итоге действовать немного иначе.
Что же, отбросим лирику и перейдем к сути статьи. Как точно выглядел код для “расскажите, какой тут будет вывод” я уже не помню, но смысл был примерно следующий:
Integer a = new Integer(127); Integer b = 127; Integer c = 127; Integer d = new Integer(128); Integer e = 128; Integer f = 128; System.out.println(a == b); System.out.println(a.equals(b)); System.out.println(b == c); System.out.println(b.equals(c)); System.out.println(d == e); System.out.println(d.equals(e)); System.out.println(e == f); System.out.println(e.equals(f));
Про упаковку (boxing) и распаковку (unboxing) между примитивными типами и эквивалентными классами-обертками, я конечно знаю, как и про кеширование определенного диапазона значений. Но вот не припомню, даже за последние 5 лет разработки исключительно на Java, о каком-либо дефекте из-за попытки сравнения Integer через оператор. А вы встречали такие проблемы на практике?
После указания всей имеющейся вереницы true/false, я озвучил, что не на сто процентов уверен по части числа 128, но, вроде, кеширование заканчивается на 127. На что собеседующий, с посылом о необходимости знать такие догмы, написал в блокноте [-128; 127].
Если заглянуть в спецификацию языка, то там можно найти отдельный раздел 5.1.7 “Boxing Conversion”, где будет упомянут такой диапазон кеширования для всех целочисленных типов. Но и обязательные требования, что выходить за рамки данного диапазона недопустимо, отсутствуют. Наоборот там прямо указывается:
Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.
И вот именно в части Integer окончание диапазона кеширования на 127 уже давно не является догмой. Даже если говорить исключительно про OpenJDK и HotSpot JVM, которые принято считать основными реализациями.
Изменить результат сравнения e и f для значения 128 можно путем задания одной опции JVM:
-Djava.lang.Integer.IntegerCache.high=128
При этом нижняя граница -128 остается зафиксированной, и не предусмотренно установки верхней границы кеширования менее 127. Также существует второй вариант указания опции через -XX:AutoBoxCacheMax, которая будет иметь приоритет над первой.
Автоматические упаковка и распаковка появились еще в 5 версии Java. А вот возможность изменения верхней границы кеширования Integer в 1.6.0_14, если верить журналам изменений.
Так что, в попытке исключить “рассказывание уже давно написанных ответов”, главное не забывать перепроверить актуальность уникальных задач из 2004 года.
P.S. Начиная с 9 версии конструкторы класса Integer помечены @Deprecated.