[英]How to return generic type T when instantiating a subclass of T
我想獲取一個可以返回T類型的對象和T的子代的參數化類
這是代碼:
import java.lang.reflect.InvocationTargetException;
class A {};
class B extends A {};
public class testGenerics<T extends A> {
T a;
T getA() {
return getA(B.class); // Compilation problem:
//The method getA(Class<T>) in the type testGenerics<T> is not applicable for the arguments (Class<B>)
}
T getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
}
我是這樣想的:
我聲明的是泛型T,它擴展了A。因此,我可以從Class clazz創建一個擴展了A的T類型的實例。
但是,當我決定從B.class獲取A時(哪個擴展了A):
getA(B.class)
我收到以下錯誤:
類型為testGenerics <T>的方法getA(Class <T>)不適用於參數(Class <B>)
為什么是這樣? 我該如何解決?
您的問題是類定義class testGenerics<T extends A>
。
這意味着T
是在創建該類的實例時定義的,並且可以綁定到A
任何子類-可能不是B
而是C
等。因此,不能保證傳遞B.class
匹配。
要解決此問題,請將T
的定義置於方法級別:
<T extends A> A getA(Class<T> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
//No generics needed here, since the method above returns A anyways.
//If it'd return T you'd have to change the return type here to B since getA(B.class) binds T to be B now
A getA() throws Exception {
return getA(B.class);
}
由於方法級別T
在類級別隱藏了定義,因此您需要為此做些事情:使用其他名稱(例如S
)或在類級別刪除定義(無論如何在這里都沒有多大意義)。
這是行不通的,因為B
不是T
是的, B
也擴展了T
,但不是T
假設您還有一個類C extends A
並創建了一個testGenerics<C>
的實例。 您的getA()
方法將實例化B
但應返回C
但是,以下內容在進行一些調整后仍然可以正常工作:
testGenerics<B> tg = new testGenerics<B>();
B b = tg.getA(B.class);
如何解決此問題取決於您實際想要做什么。 例如,這允許您實例化A
任何子類:
public <S extends A> S getA(Class<S> clazz) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return clazz.getConstructor().newInstance();
}
但是,您實際上不能在這里使用T
(例如<S extends T>
)。 由於T
是參數類型,因此不能保證B
是T
還是擴展T
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.