3 回答
TA貢獻1111條經(jīng)驗 獲得超0個贊
AnOptional<B>不是 的子類型Optional<A>。與其他編程語言不同,Java 的泛型類型系統(tǒng)不知道“只讀類型”或“輸出類型參數(shù)”,因此它不理解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調(diào)用的類型參數(shù)并傳遞 的結(jié)果,其中需要get()的實例是有效的。BA
不幸的是,這種目標類型推斷不適用于鏈式調(diào)用,因此對于
return items.stream()
.map(s -> new B())
.findFirst();
它不用于map通話。因此對于map調(diào)用,類型推斷使用的類型,new B()其結(jié)果類型將是Stream<B>. 第二個問題是它findFirst()不是泛型的,在 a 上調(diào)用它Stream<T>總是會產(chǎn)生 a Optional<T>(并且 Java 的泛型不允許聲明像 那樣的類型變量<R super T>,因此在這里甚至不可能產(chǎn)生Optional<R>具有所需類型的 a )。
→ 解決方案是為map調(diào)用提供顯式類型:
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調(diào)用提供顯式類型的解決方案。
TA貢獻1871條經(jīng)驗 獲得超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();
}
可以正常工作,取決于您的需要。
編輯:轉(zhuǎn)義一些字符
TA貢獻1860條經(jīng)驗 獲得超8個贊
AnOptional<B>不是的子類Optional<A>。
在第一種情況下,您有一個Stream<B>,因此findFirst返回一個Optional<B>,它不能轉(zhuǎn)換為一個Optional<A>。
在第二種情況下,您有一個流管道,它返回一個B. 當您將該實例傳遞給Optional.of()時,編譯器會看到該方法的返回類型是Optional<A>,因此Optional.of()返回一個Optional<A>(因為 anOptional<A>可以將 的實例B作為其值(因為Bextends A))。
添加回答
舉報
