我想知道这是 ECJ 中的错误还是对 JLS 的有效解释。
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
public class GenericsTest {
public void testInference() {
Set<Object> set1 = getCollection(HashSet::new);
Set<Object> set2 = getCollection2(HashSet::new);
}
public static <E, C extends Collection<E>> C getCollection(Supplier<C> collectionSupplier) {
return collectionSupplier.get();
}
public static <E, C extends Collection<E>> C getCollection2(CollectionSupplier<E, C> collectionSupplier) {
return collectionSupplier.get();
}
public interface CollectionSupplier<E, C extends Collection<E>> {
C get();
}
}
Javac (11.0.11) 编译一切(正确,我会说)。
ECJ (4.20.0) 无法编译getCollection2(HashSet::new)
调用并显示错误“类型不匹配:无法从集合转换为集合”。
getCollection(HashSet::new)
对于任何编译器来说,调用都不是问题。
如果我应用建议的快速修复并将强制转换插入到HashSet<Object>
,我会收到来自 ECJ 的不同错误:“在类型推断期间检测到问题:调用 getCollection2(GenericsTest.CollectionSupplier<Object,Collection>) 时出现未知错误”
这里有很多类似的问题和bugs.eclipse.org 上的错误,但大多数示例似乎都涉及?
.
请将您在演员表中遇到的问题报告给 Eclipse JDT。
作为一种解决方法,您可以给 Eclipse 编译器一个提示,如下所示:
Set<Object> set2 = getCollection2((CollectionSupplier<Object, Set<Object>>) HashSet::new);
编译器的棘手部分是检查getCollection2
返回的内容是否与Set<Object>
. 但是为了能够做到这一点,HashSet::new
必须知道的类型参数,这是由Set<Object>
(在这种情况下,HashSet::new
创建 的实例HashSet<Object>
)确定的。因此,必须从相反的方向确定类型参数,而不是检查返回类型是否与需要类型参数的声明类型兼容。
看来,Eclipse 无法计算HashSet::new
. ObjectHashSet::new
与static class ObjectHashSet extends HashSet<Object> {}
作品。GenericsTest::newObjectHashSet
withstatic Set<Object> newObjectHashSet() { return new HashSet<Object>(); }
也有效,但失败 static <T> Set<T> newObjectHashSet() { return new HashSet<T>(); }
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句