3 回答
TA贡献1111条经验 获得超0个赞
AnOptional<B>不是 的子类型Optional<A>。与其他编程语言不同,Java 的泛型类型系统不知道“只读类型”或“输出类型参数”,因此它不理解Optional<B>只提供一个实例B并且可以在需要的地方工作Optional<A>。
当我们写一个像
Optional<A> o = Optional.of(new B());
Java的类型推断使用目标类型来确定我们想要的
Optional<A> o = Optional.<A>of(new B());
这是有效的,new B()可以在需要实例的地方A使用。
这同样适用于
return Optional.of(
items.stream()
.map(s -> new B())
.findFirst()
.get()
);
其中方法声明的返回类型用于推断Optional.of调用的类型参数并传递 的结果,其中需要get()的实例是有效的。BA
不幸的是,这种目标类型推断不适用于链式调用,因此对于
return items.stream()
.map(s -> new B())
.findFirst();
它不用于map通话。因此对于map调用,类型推断使用的类型,new B()其结果类型将是Stream<B>. 第二个问题是它findFirst()不是泛型的,在 a 上调用它Stream<T>总是会产生 a Optional<T>(并且 Java 的泛型不允许声明像 那样的类型变量<R super T>,因此在这里甚至不可能产生Optional<R>具有所需类型的 a )。
→ 解决方案是为map调用提供显式类型:
public Optional<A> getItems(List<String> items){
return items.stream()
.<A>map(s -> new B())
.findFirst();
}
如前所述,仅出于完整性考虑,findFirst()它不是通用的,因此不能使用目标类型。链接允许类型更改的通用方法也可以解决问题:
public Optional<A> getItems(List<String> items){
return items.stream()
.map(s -> new B())
.findFirst()
.map(Function.identity());
}
但我建议使用为map调用提供显式类型的解决方案。
TA贡献1871条经验 获得超8个赞
您遇到的问题是泛型的继承。Optional< B > 不扩展 Optional< A >,因此不能这样返回。
我会想象这样的事情:
public Optional<? extends A> getItems( List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}
或者:
public Optional<?> getItems( List<String> items){
return items.stream()
.map(s -> new B())
.findFirst();
}
可以正常工作,取决于您的需要。
编辑:转义一些字符
TA贡献1860条经验 获得超8个赞
AnOptional<B>
不是的子类Optional<A>
。
在第一种情况下,您有一个Stream<B>
,因此findFirst
返回一个Optional<B>
,它不能转换为一个Optional<A>
。
在第二种情况下,您有一个流管道,它返回一个B
. 当您将该实例传递给Optional.of()
时,编译器会看到该方法的返回类型是Optional<A>
,因此Optional.of()
返回一个Optional<A>
(因为 anOptional<A>
可以将 的实例B
作为其值(因为B
extends A
))。
添加回答
举报