为什么编译器无法在以下示例中从Collections.emptySet()推断出结果的正确类型?
import java.util.*; import java.io.*; public class Test { public interface Option { public B option(B b, F f); } public interface F { public B f(A a); } public CollectiongetColl() { Option iopt = null; return iopt.option(Collections.emptySet(), new F >() { public Collection f(Integer i) { return Collections.singleton(i.toString()); } }); } }
这是编译器错误消息:
knuttycombe@knuttycombe-ubuntu:~/tmp/java$ javac Test.java Test.java:16: option(B,Test.F) in Test.Option cannot be applied to (java.util.Set , >>) return iopt.option(Collections.emptySet(), new F >() { ^ 1 error
现在,getColl()的以下实现当然有效:
public CollectiongetColl() { Option iopt = null; Collection empty = Collections.emptySet(); return iopt.option(empty, new F >() { public Collection f(Integer i) { return Collections.singleton(i.toString()); } }); }
并且关于集合的类型安全方法的整个意图是避免单例集合的这种问题(而不是使用静态变量.)那么编译器是否无法跨多个泛型级别执行推理?这是怎么回事?
Java需要通过推理进行大量的手工操作.类型系统可以在很多情况下更好地推断,但在您的情况下,以下将起作用:
print("Collections.emptySet();");
首先,您可以将问题范围缩小到以下代码:
public class Test { public void option(Collectionb) { } public void getColl() { option(Collections.emptySet()); } }
这不起作用,需要一个临时变量,否则编译器无法推断出类型.以下是对此问题的一个很好的解释:为什么临时变量在调用泛型方法时很重要?