考虑下面的< 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
这不仅仅是一个理论上的思考:如果这个代码被接受,它将解决我的泛型过滤问题。
谁是对的?
在适用性推断过程中,ECJ推断
List<AtomicReference#RAW> returnNull(Class<? extends AtomicReference#RAW>)
具体步骤是:
⟨类
⟨Class
T#0=原子参考#RAW
现在,传递<code>Class类型的值没有问题
(后缀#RAW是原始类型的实现特定表示,为清楚起见,此处转载)。
编辑:在调用类型推理过程中,事情看起来有所不同:通过将目标类型添加到组合中,我们最终(在合并期间)具有以下约束:
原子参考#RAW
此约束应减少为 FALSE,但 ecj 应简化为 TRUE。由此,拒绝该程序似乎是正确的答案。
我提交了错误 528970 以在 ECJ 中进行进一步调查。
这有点讽刺,因为javac有一个长期存在的错误,它错误地假定< code>T#RAW
编辑2:一年后,似乎ECJ的错误只能在JLS在JDK及其周边地区得到改进后才能修复-8054721。