[英]Java call super class constructor with generic class object
我上了這樣的課:
public class GenericClass<T> {
public void wrap(T item) {...}
}
public abstract class AbstractClass<T, G extends GenericClass<T>> {
protected G wrapper;
public AbstractClass(Class<G> generic, T something) {
wrapper = generic.newInstance();
wrapper.wrap(something);
}
public G wrapAndGet(T item) throws Exception {
wrapper.wrap(item);
return wrapper;
}
}
// 90% of the time people only need this:
public class GeneralClass<T> extends AbstractClass<T, GenericClass<T>> {
public GeneralClass(T something) {
super(GenericClass.class, something); // !error, asking for Class<GenericClass<T>>
}
}
// and use it like this:
new GeneralClass<String>("foo").wrapAndGet("bar");
// but sometimes you might need:
public class AdvancedWrapper<T> extends GenericClass<T> {
public T advancedMethod();
}
public class ClassUseAdvancedWrapper<T> extends AbstractClass<T, AdvancedWrapper<T>> {
public ClassUseAdvancedWrapper(T something) {
super(AdvancedWrapper.class, something); // error, but let's say it compiles
}
}
// then you can use:
new ClassUseAdvancedWrapper<String>("foo").wrapAndGet("bar").advancedMethod();
這對我來說沒有意義: GenericClass<T>
和GenericClass在運行時是否具有相同的類嗎? 那我怎樣才能得到GenericClass<T>
的類對象呢?
編輯:添加用例
類文字,例如。 Foo.class
,不包括泛型類型信息。 JLS州
C.class
類型為Class<C>
,其中C
是類,接口或數組類型(第C.class
)的名稱。
這也意味着表達式的類型包含原始類型,即。 在Class<GenericClass>
, GenericClass
沒有參數化,因此是原始的。
所以,這里的問題是您的抽象類的構造函數期望
Class<G> generic
G
在哪里
G extends GenericClass<T>>
如此靠近)
Class<G extends GenericClass<T>>
但是你提供
Class<GenericClass>
這些是不可分配的。
你問
那我怎樣才能得到GenericClass的類對象呢?
你不能 它不存在。 在運行時,不存在Class
為對象GenericClass<T>
這里只有一個Class
為對象GenericClass
。
您必須更詳細地說明您要嘗試執行的操作,但是可以使用以下命令編譯代碼
abstract class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<? super G> generic, T something) {
}
}
現在,您的構造函數期望Class<? super G extends GenericClass<T>>
Class<? super G extends GenericClass<T>>
並且您正在提供Class<GenericClass>
。 在您的super
構造函數調用中, GenericClass<T>
綁定到G
而GenericClass
是GenericClass<anything>
的超類型,因此Class<GenericClass>
可分配給Class<? super GenericClass<T>>
Class<? super GenericClass<T>>
。 您會發現此解決方案還有許多其他限制。 這完全取決於您的目標。
這是我需要做的一些編譯代碼。 我不知道您要做什么,但是至少這給出了一個可遵循的藍圖。 我看到的主要問題是AbstractClass
的CTOR需要兩個參數,而您不能通過僅將一個參數傳遞給GeneralClass
的CTOR來做到這一點,因此我不得不添加第二個參數。
public class GenericTest {
public static void main(String[] args) {
GenericClass<Integer> generic = null;
AbstractClass<Integer, GenericClass<Integer>> abstr = new AbstractClass( generic.getClass(), 1 );
GeneralClass<Integer, GenericClass<Integer>> general = new GeneralClass( generic.getClass(), 1 );
}
}
class GenericClass<T> {
}
class AbstractClass<T, G extends GenericClass<T>> {
public AbstractClass(Class<G> generic, T something) {
}
}
class GeneralClass<T,G extends GenericClass<T>>
extends AbstractClass<T, G> {
public GeneralClass( Class<G> generic, T something) {
super( generic, something);
}
}
編輯:因此,為了回應評論中的討論,我將AbstractClass
具體化,以便可以顯示其構造函數采用的參數。 (此外,我必須在自己的代碼中執行此操作以弄清楚到底發生了什么,因此,我正在展示自己的工作。)
我希望上面主要方法中的示例/測試用例可以清楚說明正在發生的事情。 重申Sotirios Delimanolis的看法:
How can I get the class object of GenericClass then?
你不能 它不存在。 在運行時,GenericClass沒有Class對象,GenericClass只有Class對象。
在這種情況下,GenericClass設置T =整數。 系統類Integer與您剛剛聲明的類之間顯然沒有任何關系。 沒有get()
可以調用整數來獲取類GenericClass
。 我認為我的榜樣使這一天變得平淡無奇。
您可以假設我可以制作一種處理工具,該工具可以掃描.java文件或.class文件,並建立GenericClass(及其子類?)使用的類型參數的數據庫,但是這簡直是行不通的。 如果您有足夠的資源,則可以完成此工作,但是對於最大的項目,除了最大的項目之外,其他任何項目都沒有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.