【问题标题】:Java type inference confusionJava 类型推断混淆
【发布时间】:2019-03-15 22:13:51
【问题描述】:

谁能给我解释一下,为什么编译器不会自动推断出这个表达式类型?

Stream.empty().collect(Collectors.summingInt(CharSequence::length))

我们知道CharSequence::length在这个上下文中是ToIntFunction<CharSequence>,所以从流元素中消费的类型是CharSequence,因此,被收集的流是Stream<CharSequence>类型。

在我的 IDE 上,我收到以下错误:

Stream类型中的collect(Collector super Object,A,R>)方法不适用于参数(Collector)

从错误消息中可以看出,Stream.empty() 被自动推断为 Stream<Object>,这绝对不是我想要的!

【问题讨论】:

  • 这是一个已知限制。目标类型不会通过 chained 方法调用传播。在这里,Stream.empty()collect(Collectors.summingInt(CharSequence::length)) 被链接在一起。 herehere 对此进行了解释。

标签: java-8 java-stream type-inference collectors functional-interface


【解决方案1】:

Java 的Stream.empty() 是具有以下声明的泛型方法。

public static<T> Stream<T> empty() {
   // Remainder omitted.
}

所以你必须明确地传递类型参数。否则它将创建一个java.lang.Object 类型的Stream。因此,像这样更改您的声明以消除错误。

Stream.<CharSequence>empty().collect(Collectors.summingInt(CharSequence::length));

Java 不会根据 stream 处理管道中下游操作中使用的数据类型推断类型。类型解析算法并没有你想象的那么聪明。但是,它会推断您是否将值传递给工厂方法。例如,这将起作用。

Stream.of("ab", "abc").collect(Collectors.summingInt(CharSequence::length));

【讨论】:

  • 顺便谢谢你的回答,问题是我知道如何通过在Stream.empty()方法的早期显式设置类型参数来解决这个问题。问题是为什么java没有从上下文自动推断这个,我的意思是,我确实通过Collector&lt;CharSequence, ?, Integer&gt;收集了流,这必须给java提供一个关于输入元素类型的线索CharSequence没有?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2016-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-08-23
相关资源
最近更新 更多