【发布时间】:2020-09-24 23:51:22
【问题描述】:
我有一个返回Stream 类型为A 的方法。我还有A 的子类型B。该方法创建了一个Stream,它填充了B 的实例,由于继承,这些实例也是A 类型。这很好用,直到我在Stream 上引入一个过滤器。然后,编译器决定 Stream 的类型是 B 而不是 A,继承似乎无关紧要。为什么会这样?
这是一个最小的可重现示例:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Main {
abstract class A {
int member;
}
class B extends A {
public B(int member) {
this.member = member;
}
}
public static void main(String[] args) {
Stream<A> stream = getStream();
}
private Stream<A> getStream() {
List<Integer> ints = new ArrayList<>();
ints.add(1);
ints.add(2);
ints.add(3);
return ints.stream().map(B::new).filter(b -> true); // Filter causes compiler to throw error
}
}
【问题讨论】:
-
只需在方法
getStream()中返回Stream<? extends A> -
谢谢,这似乎是一个很好的解决方案。想知道为什么我不能做我正在做的事情。
-
但是过滤器怎么会破坏一切呢?在我使用过滤器之前它工作正常。过滤器是否将
Stream<A>转换为Stream<B>? -
对了,没看到。好吧,那我只有一个不满意的答案:因为 Java 的类型推断加上泛型是疯了。就像,严重疯了。这可能与
map接受协变参数而filter接受变体参数这一事实有关。编辑:不再是这个兔子洞了...书签,如果我想出什么我会回到这里。
标签: java lambda java-stream type-inference