Я пытаюсь определить, гарантированно ли верны следующие утверждения:
((Boolean)true) == Boolean.TRUE
((Boolean)true) == Boolean.valueOf(true)
((Integer)1) == Integer.valueOf(1)
Я всегда предполагал, что автоупаковка эквивалентна вызову valueOf()
для соответствующего типа. Каждое обсуждение, которое я видел на тема кажется поддержите мое предположение. Но все, что я смог найти в JLS, это следующее (§5.1.7):
Если упаковываемое значение
p
представляет собой целочисленный литерал типаint
между-128
и127
включительно (§3.10.1), или логический литералtrue
илиfalse
(§3.10.3), или символьный литерал между'\u0000'
и'\u007f'
включительно (§3.10.3). 3.10.4), тогда пустьa
иb
будут результатом любых двух преобразованийp
в боксе. Всегда бывает так, чтоa == b
.
Это описывает поведение, идентичное, похожее* на поведение valueOf()
. Но, похоже, нет никакой гарантии, что valueOf()
действительно вызывается, а это означает, что теоретически может существовать реализация, которая хранит отдельный выделенный кеш для автоматически упакованных значений. В таком случае может не быть равенства идентичности между кэшированными автоматически упакованными значениями и обычными кэшированными упакованными значениями.
В учебнике Oracle по автоупаковке говорится, что li.add(i)
скомпилировано на li.add(Integer.valueOf(i))
, где i
– это int
. Но я не знаю, следует ли считать учебник авторитетным источником.
*Это немного более слабая гарантия, чем valueOf()
, так как она относится только к литеральным значениям.
valueOf()
; мой вопрос заключается в том, дает ли JLS какие-либо гарантии в этом отношении. - person shmosel   schedule 16.07.2015valueOf
, и ни одно из попаданий не было связано с автобоксом (только вещи оEnum.valueOf
и т. д.). По-моему, это решает. - person aioobe   schedule 06.08.2015valueOf
, или если бы javac переключился на другое решение, то любой выдаваемый новый байт-код был бы несовместим со старым байт-кодом, поскольку старый байт-код использовалvalueOf
для autoboxing, и два значения autoboxing должны (по крайней мере, при некоторых обстоятельствах) быть ссылочно эквивалентными. Теперь, чтобы связать это с формальным доказательством, нужно найти что-то в JLS, устанавливающее определенные гарантии для разделенных компиляций. Я сомневаюсь, что JLS охватывает такие темы. - person aioobe   schedule 06.08.2015Integer.valueOf
, то старый код автоупаковки не будет совместим с новым кодом автоупаковки. (Или, скорее, новый компилятор не будет совместим со старым компилятором, несмотря на то, что оба придерживаются JLS, что кажется немного противоречивым.) - person aioobe   schedule 06.08.2015valueOf
является наиболее подходящим методом для автоупаковки и что нет причин (по крайней мере, очевидных) поступать иначе. - person Jean-François Savard   schedule 06.08.2015valueOf
является подходящим и лучшим решением, но этот вопрос не об этом. - person aioobe   schedule 06.08.2015valueOf()
, поскольку разницы в поведении не будет. - person shmosel   schedule 06.08.2015valueOf
требуется. - person aioobe   schedule 06.08.2015valueOf
? ЕслиvalueOf
продолжает делать правильные вещи, я не вижу причин не вызывать его в скомпилированном классе. JVM может внедрить что-нибудь более причудливое, заменив вызов во время выполнения. Так же, как это может произойти уже сегодня. - person Holger   schedule 09.01.2020