【发布时间】:2016-05-14 16:03:41
【问题描述】:
考虑这些类和累积函数,它们代表了我原始上下文的简化(但重现了相同的问题):
abstract static class Foo {
abstract int getK();
}
static class Bar extends Foo {
int k;
Bar(int k) { this.k = k; }
int getK() { return this.k; }
}
private static Foo combined(Foo a1, Foo a2) {
return new Bar(a1.getK() + a2.getK());
}
我试图通过依赖单独的函数 combined 来执行项目的累积(最初是数据索引报告),该函数直接处理 Foo 类型的元素。
Foo outcome = Stream.of(1,2,3,4,5)
.map(Bar::new)
.reduce((a,b) -> combined(a, b))
.get();
事实证明,这段代码导致编译错误(OpenJDK“1.8.0_92”):“lambda 表达式中的返回类型错误:Foo 无法转换为 Bar”。编译器坚持尝试使用 Bar 作为累积元素来减少流,即使 Foo 作为累积函数的参数及其返回类型的公共类型也是如此。
我还发现,只要我明确地将流映射到Foos 的流,我仍然可以采用这种方法:
Foo outcome = Stream.of(1,2,3,4,5)
.<Foo>map(Bar::new)
.reduce((a,b) -> combined(a, b))
.get();
这是 Java 8 泛型类型推断的限制,Stream#reduce 的这种特殊重载的小问题,还是 Java 规范支持的有意行为?我已经阅读了其他一些关于类型推断“失败”的问题,但是这个特殊情况对我来说仍然有点难以理解。
【问题讨论】:
-
从赋值中推断的类型与从
map的参数推断的类型之间存在冲突,以确定流的类型。我认为 Java 会采用最具体的方式。
标签: java java-8 java-stream type-inference