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