泛型在Eclipse中编译和运行,但不能在javac中编译

pol*_*nts 23 java generics compiler-errors

注意:这是关于null的Comparable和Comparator合同的衍生产品

这段代码在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]"
   }
}
Run Code Online (Sandbox Code Playgroud)

但它没有编译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
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会有这种差异吗?这是一个错误吗?如果是这样,谁有错误?

Bal*_*usC 30

这是一个确认的错误:错误ID 6468354.这是相关的摘录:

这个问题是由于有时javac的JLS3 15.12.2.8的实现忽略了递归边界,有时候没有(如本例所示).当递归边界包含通配符时,在计算未推断的类型变量时会包含此类边界.这使得后续的子类型test (Integer <: Comparable<? super T>在哪里T是推断的类型变量.

将在6369605之后修复

也是在WinXP上以1.6.0_13向我发出的.好吧,我只会坚持使用Eclipse :)

  • 不,[Google](http://www.google.com/search?q=%22incompatible+types%3B+no+instance%28s%29+of+type+variable%28s%29%22+site%3Abugs .sun.com)太棒了. (21认同)
  • 天哪,你真棒! (2认同)
  • 大声笑,是的,我知道如何使用谷歌,我只是如此兴奋,只是立即发布问题=)我希望这不是"不好的问题行为",你鼓励回答它=) (2认同)

Mic*_*ael 16

您可以通过显式指定泛型类来解决这个问题:

Comparator<String> namesComp = Stack.<String>nullComparableComparator();
Run Code Online (Sandbox Code Playgroud)

  • 您可以感谢SCJP考试的答案.;) (4认同)