JDK-6714835 : Safe cast is rejected (with warning) by javac
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2008-06-16
  • Updated: 2017-05-16
  • Resolved: 2011-03-08
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 7
7 b120Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
Javac rejects a cast that is perfectly safe even without a warning.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile attached program and observe that it fails

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Should compile without warning.
ACTUAL -
Compiler rejects program

ERROR MESSAGES/STACK TRACES THAT OCCUR :
cast.java:4: incompatible types
found   : java.lang.Iterable<capture of ? extends java.lang.Number>
required: java.util.Collection<? extends java.lang.Number>
  Collection<? extends Number> x2 = x1; // javac reports error here
                                    ^
REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.*;
class cast {
    Iterable<? extends Number> x1 = null;
    Collection<? extends Number> x2 = x1; // javac reports error here
}

---------- END SOURCE ----------
Actually the problem is the following (I checked with Neal Gafter, the submitter of this bug)

import java.util.*;
class cast  {
   Iterable<? extends Number> x1 = null;
   Collection<? extends Number> x2 = (Collection<? extends Number>)x1; //javac generates a warning here
}

ACTUAL BEHAVIOR

The output is (both 6-open and 6u06)

$ javac Test.java -Xlint
Test.java:4: warning: [unchecked] unchecked cast
found   : java.lang.Iterable<capture#156 of ? extends java.lang.Number>
required: java.util.Collection<? extends java.lang.Number>
   Collection<? extends Number> x2 = (Collection<? extends Number>)x1; //javac generates a warning here
                                                                   ^
1 warning

EXPECTED BEHAVIOR

The program should compile without any warning.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/build/langtools/rev/e9e41c88b03e
04-12-2010

SUGGESTED FIX A webrev of this fix is available at the following URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/e9e41c88b03e
04-11-2010

EVALUATION The JLS mandate the warning (JLS 5.5) "A cast from a type S to a parameterized type (��4.5) T is unchecked unless at least one of the following conditions hold: 1) S <: T. 2) All of the type arguments (��4.5.1) of T are unbounded wildcards. 3) T <: S and S has no subtype XT , such that the erasures (��4.6) of X and T are the same. " Here we have that: 1) S (Iterable<? extends Number>) is *not* a subtype of T (Collection<? extends Number>) 2) T's type argument (? extends Number) is *not* an unbounded wildcard 3) There exist an *infinite) set of subtypes of S of the kind J = Collection<? extends K>, with K <: Number, such that |J| == |T| For the above reason it seems like the described cast should raise a warning. For this reason I've submitted an RFE against the JLS. Fixing this bug wouldn't be possible until JLS will tackle this issue. *** (#1 of 1): [ UNSAVED ] ###@###.###
20-06-2008