存在以下情況:
給出了一個類,其中包含一個通用字段。是否有可能在運行時使用實例T
實例化該字段?Java反射泛型 - 通過在編譯時傳遞參數進行投射?
class Root<T>{
T var;
Root(){
//instantiate var with an instance of T here
}
}
存在以下情況:
給出了一個類,其中包含一個通用字段。是否有可能在運行時使用實例T
實例化該字段?Java反射泛型 - 通過在編譯時傳遞參數進行投射?
class Root<T>{
T var;
Root(){
//instantiate var with an instance of T here
}
}
如果你有延伸Root<T>
並設置類型參數在其extends
第一個類,那麼就可以使用getGenericSuperclass()挖掘出來。例如Guice uses this approach向注入的類提供類型參數信息。
否則,最好的辦法是通過一個Class<T>
實例作爲構造函數參數並使用它。這也會導致更簡單的代碼,儘管每個類的實例化都有更多的樣板。
號
Java使用類型擦除,所以泛型參數在運行時不存在。
除非在運行時給出T
的實例,否則答案爲否,因爲java type erasure。在運行時,T實際上被替換爲Object,所以必要的信息不存在。這就是像List.toArray這樣的函數要求你傳入一個類型數組以便接收類型化結果的原因。
不。如果你真的需要這個功能,你需要在構造函數中傳入這個類型。
像這樣:
class Root<T> {
private T var;
public Root(Class<T> type) {
var = type.newInstance();
}
}
這將通過反射創建一個實例。它只會在傳入的類具有默認構造函數時才起作用。否則,你需要擴展這個例子。
因爲它在編譯時被擦除,所以在運行時無法知道T
的類型。
但是,您可以將新參數添加到類型爲Class<T>
的構造函數中。編譯器將確保傳遞的對象是與您爲Root
實例指定的T
類型對應的Class
實例。在你的構造函數,然後你可以使用反射來創建一個新型T實例:
class Root<T> {
T var;
public Root(Class<T> klass) {
var = klass.newInstance();
}
}
此假設你T
類型有一個默認的構造函數。
+1,或者只是接受一個基因工廠接口的實例。 –