第一點:您可以刪除未檢查的操作警告,將Class c
參數替換爲Class<T> c
。這可能是你所需要的......在這種情況下... = :-)
觀點二: 通常調用SomeContainer.subset()的代碼就知道在編譯輸入型U(從邏輯上下文) 。這必須是你的情況下,否則你將無法通過在Class c
參數
嘗試:
class SomeContainer<T> extends ArrayList<T>{
public <U extends T> SomeContainer subset(Class<U> c){
SomeContainer<U> output = new SomeContainer<U>();
// put filtered elements into output
return output;
}
}
見我做什麼呢?
在方法調用中引入第二個類型參數:。 也在Class<U> c
的論點中使用了這個。
調用者將調用像(其中X是選擇的T子類):
SomeContainer<X> mySubset = mySomeContainer.subset(X.class); // type inference
SomeContainer<X> mySubset = mySomeContainer.<X>subset(X.class); // type arg specified
如果你需要的東西比這更動態,通配符可以幫助 - 允許的parametised「家庭」
public SomeContainer<? extends X> subset(Class<? extends X> c){
這是一個「塑料」功能界面:類型在&出傳遞你可以返回SomeContainer<T>
或SomeContainer<X>
對於任何X是T的子類下面也適用:
public SomeContainer<? super Z> subset(Class<? extends X> c){
然而,作爲另一的海報所說,泛型是編譯時構建體,它們在替換產生的非通用代碼編譯。這意味着你不能動態地決定用一行代碼實例化泛型的類型。但是你可以作一些小小的嘗試:如果你的T的子類數量有限,比如說X,Y和Z,其中Z擴展Y,Y擴展Z,那麼你可以使用一個很老的哈希「if語句」。嘗試:
類SomeContainer擴展的ArrayList {
public SomeContainer<? extends X> subset(Class<? extends X> c){
SomeContainer<? extends X> output = null;
// would like to use: "if (c instance of Class<Z>)"
// but instanceof does not allow generic type arguments
if (c.getName().equals(Z.class.getName())) {
SomeContainer<Z> outputZ = new SomeContainer<Z>();
// put filtered elements into outputZ
output = outputZ;
} else if (c.getName().equals(Y.class.getName())) {
SomeContainer<Y> outputY = new SomeContainer<Y>();
// put filtered elements into outputZ
output = outputY;
} else if (c.getName().equals(X.class.getName())) {
SomeContainer<X> outputX = new SomeContainer<X>();
// put filtered elements into outputZ
output = outputX;
}
return output;
}
}
輕鬆! (或不)= :-)
警告是因爲您正在使用'Class'而不是'Class >'。我不確定你可以在模板參數中使用動態類型。 – vainolo
*因此它只包含特定子類型U的元素*爲什麼不用該特定子類型U聲明? – m0skit0