JDK-7034548 : Statement with generics fails to compile in one line, compiles in two lines
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u24
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2011-04-07
  • Updated: 2012-03-20
  • Resolved: 2011-04-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.
JDK 6
6Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :


ADDITIONAL OS VERSION INFORMATION :
Linux work-laptop 2.6.35-27-generic #48-Ubuntu SMP Tue Feb 22 20:25:46 UTC 2011 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
I submitted this as a bug before but included the wrong version of the code which works fine, and the bug was marked "Not Reproducible":
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7028331

This report has the correct, non-working code in it.

The compiler seems to get confused when dealing with lower bounded wildcards in generics. The code example given demonstrates the problem. The error message indicates that the compiler thinks the type should be one thing, when it seems plain that it should be another, and in fact "reminding" the compiler of the correct type via a variable declaration seems to make it happy.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the given source code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Success
ACTUAL -
Failure--see error message

ERROR MESSAGES/STACK TRACES THAT OCCUR :
<T>contains(java.util.List<T>,T) in com.foo.Foo cannot be applied to (java.util.List<java.util.Comparator<? super java.lang.Object>>,com.foo.Foo.SomeComparator<java.lang.String>)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Foo {
    public static void main(String[] args) {
        boolean b = contains(
                buildList(new SomeComparator<String>("bar")),
                new SomeComparator<String>("x"));
        System.out.println(b);
    }

    public static <T> boolean contains(List<T> objects, T  customer ) {
        return objects.contains( customer );
    }

    public static <T> List<Comparator<? super T>> buildList(Comparator<? super T>... comparator) {
        return Arrays.asList(comparator);
    }

    private static class SomeComparator<T> implements Comparator<T> {
        public SomeComparator(T arg) {}
        public int compare(T o1, T o2) { return 0; }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
"Help" the compiler recognize the correct type by splitting the problem line (first line of the main method) into two lines, like so:
        List<Comparator<? super String>> list = buildList(new SomeComparator<String>("bar"));
        boolean b = contains(
                list,
                new SomeComparator<String>("x"));

Comments
EVALUATION Note that this bug can't be fixed in JDK 6 - the JDK 6 compiler is behaving according to the inference algorithm described in JLS 3rd. In the next version of the JLS there will be changes in the inference algorithm so that the submitted program will be accepted by javac - but this means that the JDK 7 fix cannot be backported (as it won't be compliant with TCK 6).
13-04-2011

WORK AROUND User reports workaround. Replace: boolean b = contains( buildList(new SomeComparator<String>("bar")), new SomeComparator<String>("x")); with List<Comparator<? super String>> list = buildList(new SomeComparator<String>("bar")); boolean b = contains( list, new SomeComparator<String>("x")); and this compiles with previous versions of java as well as with jdk7(still).
13-04-2011

EVALUATION This has been fixed by 6650759. This code compiles as expected in JDK 7.
07-04-2011