20

我已经安装了最后一个 JDK 8 ea b114 来测试新的语言特性。然而,链式调用中的推断似乎还没有奏效。

如果我写:

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

编译器给我一个错误。

然而,论点位置的推断效果很好。

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

4

2 回答 2

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<>()不能依赖于上下文。


在问题中做你想做的事情将是对语言的巨大改变。John Rose 开始了类似的讨论,参见 http://mail.openjdk.java.net/pipermail/lambda-dev/2013-July/010531.html


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

于 2013-11-12T19:46:49.390 回答
13

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

方法调用、字段访问等(exp.foo())中的接收者不是一个多边形表达式,因为目标类型是未知的——不可能枚举具有特定成员的每个类型(foo,在这种情况下)。允许对“链”进行推理引起了一些兴趣:在 a().b() 中,将类型信息从 b 的调用传递到 a 的调用。这为推理算法的复杂性增加了另一个维度,因为部分信息必须在两个方向上传递;它仅在所有实例化(例如列表)的 a() 的返回类型的擦除固定时才有效。这个特性不能很好地适应 poly 表达式模型,因为目标类型不容易导出。

于 2013-11-12T16:33:11.740 回答