genericstypes推断不适用于方法链接?

这在Java 7中无法编译:

class Map<K,V> { static <K,V> Map<K,V> empty() {return null;} Map<K,V> put(K k, V v) {return null;} V get(K k) {return null;} } class A { static void f(Map<Integer,String> m){} public static void main(String[] args) { f(Map.empty()); } } 

它不会推断从Map.empty()返回的Map的具体types:

 $ javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty()); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error 

它编译如果你改变f调用f(Map.<Integer,String>empty()); 。 在Java 8中,它不需要求助于此。

但是如果你改变f调用f(Map.empty().put(1,"A").put(2,"B")); ,在Java 7和8上都无法再次编译。为什么?

 $ $javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error $ $javac8 A.java A.java:10: error: incompatible types: Map<Object,Object> cannot be converted to Map<Integer,String> f(Map.empty().put(1,"A").put(2,"B")); ^ Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error $ $javac8 -Xdiags:verbose A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: argument mismatch; Map<Object,Object> cannot be converted to Map<Integer,String> 1 error 

为什么?

因为genericstypes的推理没有扩展到链式调用。

从genericstypes推断的java教程 :

什么是目标types的概念已经扩展到包含方法论据。

这就是为什么这个代码:

 f(Map.empty()); 

编译。

但是这个代码并不是因为这是一个链式调用:

 f(Map.empty().put(1,"A").put(2,"B")); 

您还可以在JSR-000335 Lambdaexpression式中findJavaTM编程语言最终版本 (特别是D部分) 的一小段 :

有一些兴趣允许推断“链”:在一个()。b()中,传递types信息从调用b到调用a。 这给推理algorithm的复杂性增加了另一个维度,因为部分信息必须在两个方向上传递; 它只适用于删除a()的返回types对所有实例(例如List)都是固定的。 由于目标types不易导出,因此该特征不适合于多expression模型。 但也许还有额外的增强function,可以在未来增加。

所以也许在Java 9中。