Java 8和广义目标类型推断

时间:2013-11-12 16:12:07

标签: java generics java-8

我安装了最后一个JDK 8 ea b114来测试新的语言功能。 然而,链式调用中的推断似乎还不起作用。

如果我写:

Iterator<String> it = new ArrayList<>().iterator();

编译器给我一个错误。

然而论证位置的推论效果很好。

也许不会插入链式调用中的推断?

2 个答案:

答案 0 :(得分:17)

正如@Holger所说,Java 8改进了上下文推理,因此这可以起作用_

public static <T> Iterator<T> iter(Iterable<T> i)
{
    return i.iterator();
}

public static void main(String[] args)
{
    Iterator<String> it = iter( new ArrayList<>() );
                \____________________________/
}

它在Java 7中不起作用 - 对new ArrayList<>()的推断不能依赖于上下文。


在问题中做你想做的事情对语言来说是一个巨大的变化。约翰罗斯开始了类似的讨论,见http://mail.openjdk.java.net/pipermail/lambda-dev/2013-July/010531.html


过多的推理和过多的上下文依赖可能是一件坏事。并不是说编译器无法处理复杂性 - 它可以。这是关于人类程序员是否能够处理它。我感觉Java 8已经处于危险的水平,人类很难解析这些代码。

答案 1 :(得分:13)

最新规范(公众评论)可在jcp.org获得。 D部分有一段讨论这一点。

  

方法调用,字段访问等中的接收者(exp.foo())不是聚合表达式,因为目标类型是未知的 - 不可能枚举具有特定成员的每个类型(foo,在这种情况下)。有一些兴趣允许在a()。b()中推断&#34;链&#34;:将类型信息从b的调用传递给a的调用。这为推理算法的复杂性增加了另一个维度,因为部分信息必须在两个方向上传递;只有当a()的返回类型的擦除对于所有实例化(例如List)都是固定的时,它才有效。此特征不适合多聚表达式模型,因为无法轻松导出目标类型。