JDK-8166326 : 5.2: Allow widening before unboxing
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-09-19
  • Updated: 2018-08-03
  • Resolved: 2017-01-21
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 :  
Relates :  
Relates :  
Relates :  
Description
The rules for unboxing conversions in assignments (5.2) and various other contexts (invocation, 5.3; casting, 5.5; numeric, 5.6) assert that an unboxing may be followed by a widening primitive conversion, but do not allow a widening reference conversion before the unboxing occurs.

Despite these rules, longstanding behavior of javac is to allow, e.g., type variables to be widened to a boxed primitive type.

<T extends Integer> void test(T arg) { 
  int i = arg;
  int i2 = (int) arg;
  double d = arg + 1.0;
  Double d2 = Double.valueOf(arg);
  double d3 = (double) arg;
} 

This behavior is especially important for interoperability with capture: various existing programs expect to be able to treat the elements of a 'List<? extends Integer>' as if they were ints.

List<? extends Integer> li = null;
int i = li.get(0);

Propose to change JLS in these sections to allow a widening reference conversion before unboxing.
Comments
Changes to 5.5 are handled by JDK-8166396
20-09-2016

For clarity, add to 5.1.5: ***[Note:] The null type is not a reference type (4.1), and so a widening reference conversion does not allow conversion from the null type to a reference type. However, many conversion contexts allow the null type to be converted to a reference type.***
20-09-2016

Change to JLS 5.6: ------ Numeric contexts allow the use of: ... - an unboxing conversion (��5.1.8) ***optionally preceded by a widening reference conversion, and*** optionally followed by a widening primitive conversion [Alternatively, expand into 4 bullets, as above]
20-09-2016

Change to JLS 5.3: ------ Loose invocation contexts allow the use of one of the following: ... - a boxing conversion (��5.1.7) optionally followed by a widening reference conversion - an unboxing conversion (��5.1.8) ***optionally preceded by a widening reference conversion, and*** optionally followed by a widening primitive conversion [Alternatively, expand into 6 bullets, as above]
20-09-2016

Change to JLS 5.2: ------ Assignment contexts allow the use of one of the following: ... - a boxing conversion (��5.1.7) optionally followed by a widening reference conversion - an unboxing conversion (��5.1.8) ***optionally preceded by a widening reference conversion, and*** optionally followed by a widening primitive conversion --- or --- Assignment contexts allow the use of one of the following: ... - a boxing conversion (��5.1.7) - ***a boxing conversion followed*** by a widening reference conversion - an unboxing conversion (��5.1.8) - ***an unboxing conversion followed*** by a widening primitive conversion - ***a widening reference conversion followed by an unboxing conversion*** - ***a widening reference conversion followed by an unboxing conversion, then followed by a widening primitive conversion***
20-09-2016

I confirmed that Eclipse behavior matches javac.
20-09-2016

JDK-6558543 addressed one case���casting via widening reference followed by unboxing���but apparently didn't touch the rules in other contexts (assignment, invocation, numeric), and didn't allow a [widening reference] -> [unboxing] -> [widening primitive] chain.
19-09-2016