JDK-8033437 : javac, inconsistent generic types behaviour when compiling together vs. separate
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-02-03
  • Updated: 2014-08-04
  • Resolved: 2014-05-02
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 8 JDK 9
8u20Fixed 9 b13Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Create an empty directory and copy into it the following two sources:

Ref.java:

public class Ref<T> {
    final RefQueue<? super T> queue = new RefQueue<>();

    public static void main(String[] args) {
        Ref<Object> r = new Ref<>();
        RefQueue<Object> q = r.queue;
    }
}

RefQueue.java:

public class RefQueue<T> {}

Then execute:

    mkdir out
    javac -d out Ref.java

This compiles fine and produces two class files in out directory:

    Ref.class
    RefQueue.class

Now do the following:

    mkdir out2
    rm RefQueue.java
    javac -cp out -d out2 Ref.java

Which produces compile-time error:

Ref.java:6: error: incompatible types: RefQueue<CAP#1> cannot be converted to RefQueue<Object>
        RefQueue<Object> q = r.queue;
                              ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: Object from capture of ? super Object
1 error

reported by Peter Levart at compiler-dev: http://mail.openjdk.java.net/pipermail/compiler-dev/2014-January/008457.html
Comments
Looks like it's about order of compilation. Compiling RefQueue.java before Ref.java we'll have just the same error: $ javac RefQueue.java $ javac Ref.java Ref.java:6: error: incompatible types RefQueue<Object> q = r.queue; ^ required: RefQueue<Object> found: RefQueue<CAP#1> where CAP#1 is a fresh type-variable: CAP#1 extends Object super: Object from capture of ? super Object 1 error In this case second run of javac does not compile RefQueue.java but uses RefQueue.class instead.
24-04-2014

That's understandable. Even better, if Ref is modified to: public class Ref<T> { final RefQueue<? super T> queue = new RefQueue<>(); public static void main(String[] args) { Ref<Object> r = new Ref<>(); RefQueue<? super Object> q = r.queue; } } Then there's no error either.
06-03-2014

if Ref is modified to: public class Ref<T> { final RefQueue<T> queue = new RefQueue<>(); public static void main(String[] args) { Ref<Object> r = new Ref<>(); RefQueue<Object> q = r.queue; } } then there's no error.
05-03-2014

Release team: Approved for deferral.
06-02-2014