【问题标题】:Java 8 and Generalized Target-Type InferenceJava 8 和广义目标类型推断
【发布时间】:2019-02-14 01:30:27
【问题描述】:

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

如果我写:

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

编译器给我一个错误。

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

可能不会插入链式调用中的推理?

【问题讨论】:

  • 你最后回答了你自己的问题..
  • 这很奇怪,我可以发誓这种情况得到了很大改善......
  • @JoachimSauer 推理已得到彻底改进。方法调用和构造函数调用现在作为一个整体推断,方法接收器除外。 (顺便说一句,我还记得你在太阳论坛上。我花了一段时间才弄清楚。:D)

标签: java generics java-8


【解决方案1】:

正如@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&lt;&gt;() 的推断不能依赖于上下文。


要在问题中做你想做的事情,这将是一个巨大的语言变化。 John Rose 发起了类似的讨论,请参阅http://mail.openjdk.java.net/pipermail/lambda-dev/2013-July/010531.html


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

【讨论】:

  • 嗯,我看到邮件列表中的例子有一些极端情况,其中类型推断可能会影响选择哪个重载方法。但我真的希望他们为 99% 的不存在重载方法的情况(如 iterator() 示例)实现类型推断,并仅对重载方法禁止它,而不是仅仅因为这 1% (或更少)极端情况。
  • “我感觉到 Java8 已经处于人类难以解析代码的危险水平。” IDE 的特性,如 method-signature-on-hover(显示推断的泛型类型信息)使得解析此类事情变得更加容易。
  • Iterator a=new ArrayList().iterator(); ,虽然让我在 Java 8 中编译错误。
【解决方案2】:

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

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

【讨论】:

  • 听起来他们想再次强迫我们在我们的代码中添加过时的辅助方法,只是为了让编译器满意...... :-(
  • @Holger 我只能说这是一个非常的难题。从事规范和实施工作的人是一群聪明的人。他们也编写 Java 代码,我相信他们希望代码尽可能愉快。所以他们让它变得没有想象中那么愉快,我怀疑这是因为缺乏尝试。
  • 我毫不怀疑他们很聪明,而且工作努力。我仍然不明白为什么可以通过遵循始终相同模式的通用包装方法解决的问题应该是任何形式问题。顺便说一句,Java 5 在创建实例时重复每个类型参数的要求在 Java 7 中已被删除,这一事实证明从来没有真正需要它。它背后的逻辑在 Java 5 和 Java 7 之间没有改变。所以他们之前没有尝试(足够)。那么也许 Java 10 会证明 Java 8 限制背后的原因从来都不是问题?
  • @Holger 这两个难度不同。就推理而言,构造函数有点像静态方法;这更像是 java5 中的疏忽,不对构造函数进行推断。链式方法调用是完全不同的动物。
  • john rose发起的一些相关讨论-mail.openjdk.java.net/pipermail/lambda-dev/2013-July/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 2014-03-20
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
相关资源
最近更新 更多