Should JLS 5.1.7 require that boxing uses `valueOf`?
Brian Goetz
brian.goetz at oracle.com
Sat Mar 9 16:52:10 UTC 2024
In general, the specification does not prescribe most details of how a source program is translated into classifies. (Some exceptions are made in the section on binary compatibility.). This is a deliberate design choice; the JLS defines the meaning of a Java program, but not a prescriptive recipe for compiling it into a classfile.
> On Mar 9, 2024, at 8:28 AM, some-java-user-99206970363698485155 at vodafonemail.de wrote:
>
> 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