当前位置: 首页 > 面试题库 >

为什么隐式类型推断仅在分配中起作用?

哈栋
2023-03-14
问题内容

我知道在分配中使用泛型时,方法可以通过查看左侧变量的类型隐式地知道返回类型的类型。

来自Google收藏夹的示例:

List<String> l = Lists.newArrayList()

我的问题是为什么它不适用于方法或更高类型的推理?

例:

List<List<String>> ll = Lists.newArrayList();
ll.put(Lists.newArrayList()); // doesn't work

是在JLS中指定的吗?如果是,为什么?如果没有,那么这是我可以期望从Java 7获得的一种改进吗?

这让我很烦,因为似乎我们在Java中遇到了问题,就像很久以前在Delphi中就遇到问题一样,在该问题中我无法进行链式方法调用,例如:

C c = a.b().c();

在Delphi(IIRC)中,您必须执行以下操作:

B b = a.b();
C c = b.c();

看起来像个“似曾相识”


问题答案:

我不想在这里要求特别的知识,但是将变量赋值和将值用作方法参数之间有一个明显的区别:在前一种情况下,无论方法是否重载,都只有一个 可能的 目标。

基本上,这意味着您不必担心类型推断和重载/转换之间的相互作用: 当您知道自己感兴趣的唯一目标类型时,才进行推断。

刚刚虽然猜测。我总是发现Java的类型推断很有趣-它的工作方式与C#3完全相反,在C#3中,您可以推断 变量的 类型(只要它是局部变量)。

编辑:我相信相关的JLS节是15.12.2.8:

如果方法结果发生在将进行赋值转换(第5.2节)为类型S的上下文中,则使R为方法的声明结果类型[…]

基本上,“分配转换”位很重要。



 类似资料:
  • 问题内容: 我正在使用Java 的本地实现,该实现具有如下方法: 这两种方法可以编译并正常工作: 此方法无法编译: 错误: (我已经修剪了包限定符,以使错误更易读) 我可以通过指定类型进行编译: 但是为什么我需要呢?以及如何避免此代码混乱? 问题答案: 此代码应该起作用。 它在最新的JDK 1.8.0_121上编译。 无法在JDK 1.8.0-51上编译。 这意味着它在此版本的JDK中很可能是一个

  • 看看下面例子中泛型类型的类型推断,我说不出为什么工作得很好,但是(几乎相同)无法编译,为了管理它,编译器需要额外的技巧,比如或。 导致编译器不确定表达式类型和方法结果类型是否兼容的问题是什么?

  • 我使用的是Java中的<code>或者</code>的本地实现,它有如下方法: 这两种方法可以编译并正常工作: 此方法不编译: 错误: (我去掉了包限定符,使错误更加易读) 我可以通过指定类型来编译它: 但我为什么需要这样做?我如何避免这种代码混乱?

  • 在一个actor中(这里我只是使用一个名为的常规对象,因为这个问题并不是akka特有的),我正在进行模式匹配并调用一个函数,该函数对我的有效负载类型进行操作。 由于我不理解的原因,使用和未应用的case类进行模式修补不会推断出的类型参数。在上面的代码中,我希望的类型为。但是,当我编译时,它认为类型是。 这是意料之中的行为吗?如果是的话,我对Scala中的类型推断有什么误解?

  • 问题内容: 说,我有一种方法: 然后在尝试编译此代码时: 我得到一个错误。谁能解释为什么类型系统不能推断Collections.emptyList()应该是类型吗? 上面的示例显然是很人为的,但是我一直都在偶然地遇到这种限制,这确实很烦人。阅读了 Effective Java 之后,我发现您可以轻松地完成工作(必须说,当时对我来说是一个启示),并且一切都可以顺利编译,但是当您使用复杂的类型时,确实