想象以下類層次結構:
Cake
\- ChocolateCake
\- StuffedChocolateCake
\- VanillaCake
我想撰寫一個方法來組合 ChocolateCake 和 VanillaCake 的串列,例如:
public static <T extends Cake> List<T> union(List<T> listA, List<T> listB) {
List<T> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
這會引發我理解的編譯錯誤:
inferred type does not conform to equality constraint(s)
我嘗試洗掉平等約束做這樣的事情:
public static List<? extends Cake> union(List<? extends Cake> listA, List<? extends Cake> listB) {
List<? extends Cake> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
我想這是 Java 泛型的一個相當基本的場景,正確的方法是什么?
在此先感謝您的時間!
uj5u.com熱心網友回復:
將回傳型別更改為List<Cake>,您的第二個版本應該可以正常作業:
public static List<Cake> union(List<? extends Cake> listA, List<? extends Cake> listB) {
List<Cake> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
如果您希望該選項回傳一些常見的子型別Cake,您可以將通配符與通用引數結合起來:
public static <T extends Cake> List<T> union(List<? extends T> listA, List<? extends T> listB) {
List<T> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
uj5u.com熱心網友回復:
您現有的代碼只能合并兩個完全相同型別的串列。但是,您可以將型別簽名(其余代碼保持不變)更改為
public static <T extends Cake> List<T> union(
List<? extends T> listA, List<? extends T> listB
)
在這種情況下,您是說這兩個串列可以是任何型別,只要該型別是 的子型別T,即 的子型別Cake。
uj5u.com熱心網友回復:
package cake;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static List<Cake> unionB(List<Cake> listA, List<Cake> listB) {
List<Cake> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
public static List<Cake> unionC(List<ChocolateCake> listA, List<VanillaCake> listB) {
List<Cake> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
public static List<Cake> unionD(List<? extends Cake> listA, List<? extends Cake> listB) {
List<Cake> returnObject = new ArrayList<>();
returnObject.addAll(listA);
returnObject.addAll(listB);
return returnObject;
}
public static void setB() {
List<Cake> a = new ArrayList<>();
a.add(new ChocolateCake());
List<Cake> b = new ArrayList<>();
b.add(new VanillaCake());
unionB(a, b);
}
public static void setC() {
List<ChocolateCake> a = new ArrayList<>();
a.add(new ChocolateCake());
List<VanillaCake> b = new ArrayList<>();
b.add(new VanillaCake());
unionC(a, b);
}
public static void setD() {
List<ChocolateCake> a = new ArrayList<>();
a.add(new ChocolateCake());
List<VanillaCake> b = new ArrayList<>();
b.add(new VanillaCake());
unionD(a, b);
}
}
這三種方法也行。
- unionB、unionC、unionD的引數型別取決于你的實際引數,當我們需要像這樣的型別時
? extends T,一般是有一個容器,容器需要保持從T繼承的不同型別。這種情況下,T就是Cake。 ? extends T容器不能更新,所以你的第二種方法會導致編譯錯誤。- 您將三個方法的回傳型別更改為 List<? 擴展蛋糕>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/439668.html
下一篇:有條件地傳遞傳播物件作為道具
