JDK-8168269 : Javac compile error on cast to primitive when using generics wirldcards
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2016-10-18
  • Updated: 2017-01-05
  • Resolved: 2017-01-05
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
tbd_majorResolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
The following program does not compile using javac (but does compile using the eclipse compiler).

  public static void main(String... s) {
    List<?> l = Arrays.asList(1, 2, 3, 4);
    if (l.get(0) instanceof Integer) {
      System.out.println((int) l.get(0));
    }
  }

incompatible types: capture#1 of ? cannot be converted to int


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
  public static void main(String... s) {
    List<?> l = Arrays.asList(1, 2, 3, 4);
    if (l.get(0) instanceof Integer) {
      System.out.println((int) l.get(0));
    }
  }

-> incompatible types: capture#1 of ? cannot be converted to int
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
  public static void main(String... s) {
    List<?> l = Arrays.asList(1, 2, 3, 4);
    if (l.get(0) instanceof Integer) {
      System.out.println((Integer) l.get(0));
    }
  }

-> OK ! Just changing from primitive to object


Comments
javac behavior has already been fixed by JDK-8144832.
05-01-2017

Per the spec revisions of JDK-8166396, the cast from a type variable `T` to primitive type `int` is a narrowing reference conversion (T --> Integer, allowed because upper(T) --> Integer is allowed) followed by an unboxing conversion (Integer --> int).
05-01-2017

Reopening: I didn't realize that "narrowing reference conversion" was defined to support various things that I'd describe as widening followed by narrowing. It's a spec bug that 5.1.6 has evolved independently of 5.5.1, when arguably they should be asserting the same things. We'll need to sort this bug out in order to decide whether converting from a type variable to Integer is a legal "narrowing reference conversion".
08-12-2016

JDK-8166396 examines the possible combinations of conversions supported by casting. Unboxing casts are not the same as reference-to-reference casts, and do not support widening (to Object) before narrowing (to Integer) and then unboxing (to int). The workaround, if the unboxing is necessary and won't happen implicitly, is to use two casts: System.out.println((int)(Integer) l.get(0));
06-12-2016

Difference of behaviour observed in Eclipse and Java compiler Eclipse compiles correctly the attached Test.java file. Where as it is an issue in 8u112 8u112 - Fail == -sh-4.1$ /opt/java/jdk1.8.0_112/bin/javac Test.java Test.java:9: error: incompatible types: CAP#1 cannot be converted to int System.out.println((int) l.get(0)); ^ where CAP#1 is a fresh type-variable: CAP#1 extends Object from capture of ? == 9 ea b-139 - Pass
19-10-2016