泛型在Eclipse中可以编译和运行,但在javac中无法编译。
泛型在Eclipse中可以编译和运行,但在javac中无法编译。
注意:这是从Comparable和Comparator与null相关的问题派生出来的。
这段代码在Eclipse(20090920-1017)中可以编译和运行正常。
import java.util.*; public class SortNull { static> Comparator nullComparableComparator() { return new Comparator () { @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 numbers = new ArrayList ( Arrays.asList(3, 2, 1, null, null, 0) ); Comparator numbersComp = nullComparableComparator(); Collections.sort(numbers, numbersComp); System.out.println(numbers); // "[null, null, 0, 1, 2, 3]" List names = new ArrayList ( Arrays.asList("Bob", null, "Alice", "Carol") ); Comparator 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.Comparatorconforms to java.util.Comparator found : java.util.Comparator required: java.util.Comparator Comparator numbersComp = nullComparableComparator(); SortNull.java:25: incompatible types; no instance(s) of type variable(s) T exist so that java.util.Comparator conforms to java.util.Comparator found : java.util.Comparator required: java.util.Comparator Comparator namesComp = nullComparableComparator(); 2 errors
是否有人可以解释这个差异是为什么?这是一个错误吗?如果是的话,是谁有问题?
问题的出现原因是一个已确认的bug,bug编号为6468354。具体原因是由于javac的实现在计算未推断类型变量时有时会忽略递归边界,有时不会(就像这个案例中一样)。当递归边界包含通配符时,这些边界在计算未推断类型变量时会被包括进去。这会导致后续的子类型检查出错,例如:test (Integer <: Comparable<? super T>
,其中T
是一个需要推断的类型变量)。这个问题将在修复了6369605之后得到解决。
解决方法是使用Eclipse编译和运行代码,因为Eclipse对这个bug进行了处理。在Eclipse中,代码可以成功编译和运行。另外,也可以使用其他的Java编译器,只要不是javac即可。
总结起来,这个问题的出现原因是javac编译器中的一个已确认的bug,解决方法是使用Eclipse或其他Java编译器。