Should JLS 5.1.7 require that boxing uses `valueOf`?

some-java-user-99206970363698485155 at vodafonemail.de some-java-user-99206970363698485155 at vodafonemail.de
Sat Mar 9 16:28:19 UTC 2024


Hello,

currently the JLS 21 §5.1.7 [1] does not say how exactly boxing should 
be performed, that is, conversion
from primitive to wrapper types such as `int` -> `Integer`. But it does 
mention that boxing certain
values, such as integers in range -128 to 127, should produce the same 
instances:
 > then let a and b be the results of any two boxing conversions of p. 
It is always the case that a == b

In particular it does not mention that the `valueOf` method has to be 
used (e.g. `Integer.valueOf(int)`).

As pointed out in https://stackoverflow.com/q/31445024 (and the comments 
there), that can be
problematic because if compiler A and compiler B implement this required 
caching in different ways
where both compilers in isolation adhere to the JLS, but using the 
produced class files together
could violate the JLS.

The situation also got worse when 
https://bugs.openjdk.org/browse/JDK-7190924 accidentally (?) made the
JLS more strict. Before the changes it said:
 > If the value p ...

Now it says:
 > If the value p being boxed is the result of _evaluating a constant 
expression_ ...

So if one refactors their code and the boxed primitive is not a constant 
expression anymore, they
cannot rely on these guarantees of same boxed instances anymore.

At this point it is not completely clear how much value this JLS 
sentence about producing same boxed
instances really adds, if separate compilers can implement it in 
incompatible ways and if it does not
actually apply in many situations anymore (all cases with non-constant 
values).

On the other hand, most (if not all) compilers are using `valueOf` 
anyway, and the `valueOf` methods
are implemented with the caching required by the JLS, and their 
documentation guarantees this behavior,
see for example https://bugs.openjdk.org/browse/JDK-6628737.

So would it make sense that the JLS requires that `valueOf` is used?
(This would also have the nice side effect that this JLS section could 
be simplified and would not
need these verbose bullet points about how the boxed value behaves 
compared to the primitive value.
Though of course this shouldn't be the main motivation for this change.)
The requirement that producing the same boxed instances only applies to 
constant expressions can
then be removed again as well.


Kind regards


[1] https://docs.oracle.com/javase/specs/jls/se21/html/jls-5.html#jls-5.1.7


More information about the discuss mailing list