Generics компилируется и запускается в Eclipse, но не компилируется в javac

Примечание. Это побочный результат из договора сравнения и компаратора относительно нулевого

Этот код компилируется и работает отлично в Eclipse (20090920-1017)

import java.util.*;
public class SortNull {
   static <T extends Comparable<? super T>>
   Comparator<T> nullComparableComparator() {
      return new Comparator<T>() {
         @Override public int compare(T el1, T el2) {
         return
            el1 == null ? -1 :
            el2 == null ? +1 :
            el1.compareTo(el2);
         }
      };
   }
   public static void main(String[] args) {
      List<Integer> numbers = new ArrayList<Integer>(
         Arrays.asList(3, 2, 1, null, null, 0)
      );
      Comparator<Integer> numbersComp = nullComparableComparator();
      Collections.sort(numbers, numbersComp);
      System.out.println(numbers);
      // "[null, null, 0, 1, 2, 3]"

      List<String> names = new ArrayList<String>(
         Arrays.asList("Bob", null, "Alice", "Carol")
      );
      Comparator<String> namesComp = nullComparableComparator();
      Collections.sort(names, namesComp);
      System.out.println(names);
      // "[null, Alice, Bob, Carol]"
   }
}

И все же он не компилируется на javac 1.6.0_17. Это сообщение об ошибке:

SortNull.java:17: incompatible types; no instance(s) of type variable(s) T exist
 so that java.util.Comparator<T> conforms
 to java.util.Comparator<java.lang.Integer>
found   : <T>java.util.Comparator<T>
required: java.util.Comparator<java.lang.Integer>
     Comparator<Integer> numbersComp = nullComparableComparator();

SortNull.java:25: incompatible types; no instance(s) of type variable(s) T exist
 so that java.util.Comparator<T> conforms
 to java.util.Comparator<java.lang.String>
found   : <T>java.util.Comparator<T>
required: java.util.Comparator<java.lang.String>
     Comparator<String> namesComp = nullComparableComparator();

2 errors

Может кто-нибудь объяснить, почему расхождение? Это ошибка? Если да, у кого есть ошибка?

Ответ 1

Это подтвержденная ошибка: Идентификатор ошибки 6468354. Здесь выдержка релевантности:

Эта проблема вызвана тем, что иногда реализация javac JLS3 15.12.2.8 игнорирует рекурсивные границы, иногда нет (как в этом случае), Когда рекурсивные границы содержат подстановочные знаки, такие ограничения включаются при вычислении переменных неинтерпретируемого типа. Это делает последующий подтипирование test (Integer <: Comparable<? super T>, где T является переменной типа, которая должна быть выведена).

Будет исправлено после 6369605

Происходит мне и на WinXP с 1.6.0_13. Хорошо, я просто буду использовать Eclipse:)

Ответ 2

Вы можете обойти это, явно указав общий класс:

Comparator<String> namesComp = Stack.<String>nullComparableComparator();

Ответ 3

У меня была аналогичная проблема и она была обновлена ​​с jdk1.6.0_16 до jdk1.6.0_23, и она исчезла без каких-либо изменений кода.