【问题标题】:Generics compiles and runs in Eclipse, but doesn't compile in javac泛型在 Eclipse 中编译和运行,但在 javac 中不编译
【发布时间】:2011-02-20 23:24:43
【问题描述】:

注意:这是Comparable and Comparator contract with regards to null的衍生产品

这段代码在 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

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

【问题讨论】:

    标签: java generics compiler-errors


    【解决方案1】:

    这是一个已确认的错误:Bug ID 6468354。以下是相关性摘录:

    这个问题是由于 javac 的 JLS3 15.12.2.8 实现有时会忽略递归边界,有时不会(如本例)。当递归边界包含通配符时,计算未推断类型变量时会包含此类边界。这使得后续的子类型 test (Integer &lt;: Comparable&lt;? super T&gt; 其中T 是一个类型变量被推断)。

    将在6369605之后修复

    在 WinXP 上也出现了 1.6.0_13。嗯,我会坚持使用 Eclipse :)

    【讨论】:

    • 不,Google 很棒。
    • LOL 是的,我知道如何使用谷歌,我只是太兴奋了,马上发布问题 =) 我希望这不是你鼓励的“不良问题行为”通过回答它=)
    【解决方案2】:

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

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

    【讨论】:

    • 正是我想要的!
    【解决方案3】:

    我遇到了类似的问题,从 jdk1.6.0_16 升级到 jdk1.6.0_23,它就消失了,没有任何代码更改。

    【讨论】:

    • 我有 1.6.0_24 Java 编译器,不幸的是这个问题出现了。 Sun 的错误数据库将修复版本指定为 7(b109)(我假设它是 JDK7),所以您可能只是运气好;)在明确指定类型之后,正如 Michael 所建议的,一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多