Summary: | [1.5][compiler] javac reports errors, Eclipse not -- incompatible types | ||
---|---|---|---|
Product: | [Eclipse Project] JDT | Reporter: | Hendrik Maryns <hendrik> |
Component: | Core | Assignee: | Philipe Mulet <philippe_mulet> |
Status: | RESOLVED DUPLICATE | QA Contact: | |
Severity: | normal | ||
Priority: | P3 | CC: | daniel_megert |
Version: | 3.2 | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | Linux | ||
Whiteboard: |
Description
Hendrik Maryns
2006-09-25 06:03:14 EDT
Let's make the example a bit more concise, and with numbered testcases: import java.util.Comparator; @SuppressWarnings("unchecked") class ComparableComparator<T extends Comparable<? super T>> implements Comparator<T> { static ComparableComparator instance = new ComparableComparator(); public static <W extends Comparable<? super W>> ComparableComparator<W> getInstance() { return instance; } static <M extends Comparable<M>> Comparator<M> bar() { return null; } public int compare(T obj1, T obj2) { return obj1.compareTo(obj2); } } @SuppressWarnings("unchecked") class ComparatorUtils { static Comparator BAR = ComparableComparator.bar();//0 static Comparator NATURAL_COMPARATOR = ComparableComparator.getInstance();//1 public static <T extends Comparable<? super T>> Comparator<T> naturalComparator() { return NATURAL_COMPARATOR; } public static <U> Comparator<U> nullLowComparator(Comparator<U> comparator) { if (comparator == null) comparator = (Comparator<U>) naturalComparator();//2 return new NullComparator<U>(comparator, false); } } @SuppressWarnings("unchecked") class NullComparator<V> implements Comparator<V> { Comparator<V> nonNullComparator; boolean nullsAreHigh; public NullComparator() { this((Comparator<V>) ComparableComparator.getInstance(), true);//3 } public NullComparator(Comparator<V> nonNullComparator) { this(nonNullComparator, true); } public NullComparator(boolean nullsAreHigh) { this((Comparator<V>) ComparableComparator.getInstance(), nullsAreHigh);//4 } public NullComparator(Comparator<V> nonNullComparator, boolean nullsAreHigh) { this.nonNullComparator = nonNullComparator; this.nullsAreHigh = nullsAreHigh; if (nonNullComparator == null) { throw new NullPointerException("null nonNullComparator"); } } public int compare(V obj1, V obj2) { return 0; } } javac says: X.java:22: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) M found : <M>java.util.Comparator<M> required: java.util.Comparator static Comparator BAR = ComparableComparator.bar();//0 ^ X.java:23: incompatible types; inferred type argument(s) java.lang.Comparable<? super W> do not conform to bounds of type variable(s) W found : <W>ComparableComparator<W> required: java.util.Comparator static Comparator NATURAL_COMPARATOR = ComparableComparator.getInstance();//1 ^ X.java:31: incompatible types; inferred type argument(s) java.lang.Comparable<? super T> do not conform to bounds of type variable(s) T found : <T>java.util.Comparator<T> required: java.lang.Object comparator = (Comparator<U>) naturalComparator();//2 ^ X.java:43: incompatible types; inferred type argument(s) java.lang.Comparable<? super W> do not conform to bounds of type variable(s) W found : <W>ComparableComparator<W> required: java.lang.Object this((Comparator<V>) ComparableComparator.getInstance(), true);//3 ^ X.java:51: incompatible types; inferred type argument(s) java.lang.Comparable<? super W> do not conform to bounds of type variable(s) W found : <W>ComparableComparator<W> required: java.lang.Object this((Comparator<V>) ComparableComparator.getInstance(), nullsAreHigh);//4 ^ 5 errors Problem (0) seems to be a duplicate of bug 121369, which traces back to a bug in javac & spec, which haven't been resolved so far (spec has a hole, and javac doesn't provide a definite answer. We provide a slightly better answer (one more substitution) but we need the JLS to be fixed to agree on the final result. We believe that Eclipse support is closer to where the JLS should end up at. (Note that problem 0 did not exist in your original testcase) Problem (1) is another instance of the same issue in javac. Mishandling of inferred parameter type, where bound is mutually recursive. If eliminating the self-reference in type parameter bound, examples are working again, e.g. class ComparableComparator { static <M extends String> Comparator<M> baz() { return null; } } class ComparatorUtils { static Comparator BAR3 = ComparableComparator.baz();//1b } Problems are again the same. Added GenericTypeTest#test1035. Closing as dup of bug 121369 *** This bug has been marked as a duplicate of 121369 *** |