JDK-7190924 : 5.1.7: JLS does not mention caching of autoboxed longs
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2012-08-13
  • Updated: 2020-02-22
  • Resolved: 2016-09-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

But long is cached the same as int and short, but this is not mentioned.  Is it an oversight or is it deliberately unspecified.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should state that long is cached or state that long may or may not be cache.
ACTUAL -
long, float and double are not specified.

long is cached, float and double are not, so you cannot assume anything from their absence.


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
Read the code for OpenJDK instead of the JLS. :(

SUPPORT :
YES

Comments
Per StackOverflow (https://stackoverflow.com/questions/59555374/is-caching-of-boxed-byte-objects-not-required-by-java-13-se-spec), the paragraph should have read: "If the value p being boxed is the result of evaluating a constant expression of type boolean, *****byte,***** char, short, int, or long, and the result is true, false, a character in the range \u0000 to \u007f (inclusive), or an integer in the range -128 to 127 (inclusive), then let ...". Separately, requiring the boxing of constant expressions in-range, and allowing but not requiring the boxing of other expressions in-range, makes sense if the JLS is trying primarily to assist a programmer's understanding of boxed objects while they read source code.
22-02-2020

It is erroneous to delineate the value p in terms of boolean/character/integer literals, because it rules out suitably-typed constant expressions whose results are, indeed, subject to the flyweight pattern. Also, it is obtuse to ignore long values in the specification, because it turns out that javac has always flyweighted the integers -128..127 that result from constant expressions of type long. Here's a suggested fix: "If the value p being boxed is the result of evaluating a constant expression of type boolean, char, short, int, or long, and the result is true, false, a character in the range \u0000 to \u007f (inclusive), or an integer in the range -128 to 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2." Also remove the informative sentence: "Notice that integer literals of type long are allowed, but not required, to be shared."
22-02-2020

In their wisdom, the JSR 201 expert group did not require (but did allow) autoboxing of long values. The JLS maintenance lead can have final say about whether or not this merits a more explicit note in the JLS.
15-04-2016

My belief is that it's the library that does the actual flyweighting. Javac just defers to the library by calling valueOf() for boxing conversions (at least, it does so for the cases I checked). In any case, the library specifies caching for Boolean and Byte, and for Character, Short, and Integer values within the usual range. The library does caching for Long values within the range, but it doesn't specify that it does so; it merely mentions that doing so is allowed. If work is done in this area in the JLS and/or javac, we should make sure to consider adjusting the library specifications or implementations as well.
14-04-2016

EVALUATION It's worth recording in an informative note that integer values in -128 and 127 (inclusive) which are of type long are allowed, but not required, to be cached. In fact, the flyweight rule from JLS3 is unclear. First, it speaks of "an int or short number" but what is a "number"? Is it a literal? If so, then are all integer literals between -128 and 127 (inclusive) to be autoboxed, including those suffixed by 'L'? Second, the text speaks of "a byte", but byte is a type, not a value. The value '3' can be assigned to a variable of type byte, but '3' is an integer literal of type int, so what exactly is "a byte"? I think the rule should be stated as follows: If the value p being boxed is the boolean literal 'true' or 'false' (JLS 3.10.3), or a character literal in the range \u0000 to \u007f (JLS 3.10.4), or an integer literal of type int between -128 and 127 (inclusive) (JLS 3.10.1), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2." Notice that an integer literal of type long is not required to participate in the flyweight pattern.
14-08-2012