JDK-8220612 : Method reference allows unboxing without cast
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9,10,11,12
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2019-03-13
  • Updated: 2019-03-13
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.
Other
tbdUnresolved
Related Reports
Relates :  
Description
Scenario: a reference to a method with a type variable return type that is instantiated to a box type (Integer, Long, Double, etc.), used to implement a method with a primitive return type.

If heap pollution allows a Number of some other type to be returned at run time, conversion to the primitive type happens without error. No cast check is performed. A narrowing primitive conversion may occur.

List<Integer> li = new ArrayList<>();
List lraw = li;
lraw.add(23.8); // unchecked warning

IntUnaryOperator f1 = li::get;
f1.applyAsInt(0); // result: 23

// for comparison
Function<Integer,Integer> f2 = li::get;
f2.apply(0); // CCE: can't convert Double to Integer

Per JLS 15.13.3, "the body returns the result of the method invocation or object creation, after any necessary assignment conversions (��5.2)." The conversion being applied here is Integer-->int, and we'd expect a CCE to occur if the object to be converted is not an Integer.

Comments
JDK-8174983 will change the runtime behavior, preventing narrowing primitive conversions. It will still allow *widening* primitive conversions, which is not consistent with the spec. List<Integer> li = new ArrayList<>(); List lraw = li; lraw.add(Short.valueOf((short)23)); // unchecked warning IntUnaryOperator f1 = li::get; f1.applyAsInt(0); // result: 23 Can be addressed by changing the 'instantiatedMethodType' parameter from, e.g., '(I)I' to '(I)Ljava/lang/Integer;'. (Status quo is that primitives in the 'samMethodType' are always identical in the 'instantiatedMethodType', so doing this won't lose any information). However, that conversion will only be allowed for target versions >= N, where N is the first version to include the JDK-8174983 changes.
13-03-2019