提问者:小点点

Eclipse ECJ接受这段代码,javac不接受——谁是对的?


考虑下面的< code>returnsNull函数以及对它的泛型类型调用:

public static <T> List<T> returnNull(Class<? extends T> clazz) {
    return null;
}

public static void main( String[] args )
{
    List<AtomicReference<?>> l = returnNull(AtomicReference.class);
}

当设置为 Java 8时,Eclipse编译器接受它,但 Java 8中的javac拒绝它:

incompatible types: cannot infer type-variable(s) T
    (argument mismatch; java.lang.Class<java.util.concurrent.atomic.AtomicReference> cannot be converted to java.lang.Class<? extends java.util.concurrent.atomic.AtomicReference<?>>)

潜在的区别似乎是给定两个参数化类型< code>P1

这不仅仅是一个理论上的思考:如果这个代码被接受,它将解决我的泛型过滤问题。

谁是对的?


共1个答案

匿名用户

在适用性推断过程中,ECJ推断

List<AtomicReference#RAW> returnNull(Class<? extends AtomicReference#RAW>)

具体步骤是:

  • 初始约束:<ul>
  • ⟨类
  • ⟨Class
  • T#0=原子参考#RAW

现在,传递<code>Class类型的值没有问题

(后缀#RAW是原始类型的实现特定表示,为清楚起见,此处转载)。

编辑:在调用类型推理过程中,事情看起来有所不同:通过将目标类型添加到组合中,我们最终(在合并期间)具有以下约束:

  • 原子参考#RAW

此约束应减少为 FALSE,但 ecj 应简化为 TRUE。由此,拒绝该程序似乎是正确的答案。

我提交了错误 528970 以在 ECJ 中进行进一步调查。

这有点讽刺,因为javac有一个长期存在的错误,它错误地假定< code>T#RAW

编辑2:一年后,似乎ECJ的错误只能在JLS在JDK及其周边地区得到改进后才能修复-8054721。