为什么 Stream#reduce 不隐式接受处理超类型元素的累积函数?
考虑到这些类和累积函数,它们代表了我原始上下文的简化(但再现了相同的问题):
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
我还发现奇怪的是,只要我显式地将流映射到s流中,我仍然可以采用这种方法:Foo
Foo outcome = Stream.of(1,2,3,4,5)
.<Foo>map(Bar::new)
.reduce((a,b) -> combined(a, b))
.get();
这是 Java 8 的泛型类型推断的局限性,还是 Java 规范支持的有意行为?我已经阅读了一些关于SO的其他问题,其中类型推断“失败”,但这种特殊情况对我来说仍然有点难以掌握。Stream#reduce