[英]Create an instance of the given Class type
我有一些子類,所有這些子類都由一個公共父類擴展。
我想要的是父類中的一個具體方法,該方法應返回給定類類型的新對象。
這就是我嘗試過的。
class Vehicle {
public <T> T get(Class<T> type){
//return new T();
}
}
class Car extends Vehicle {
}
class Van extends Vehicle {
}
上面的get(...)
方法
return new T();
語句給出了一個編譯錯誤,
意外的類型
必填:類
找到:類型參數T
我無法直接創建子類的對象,例如,
new Car();
由於某些原因。 可以有任意數量的子類,因此在每個子類中覆蓋get()
方法也不是一種選擇。 任何想法?
您可以使用Class.newInstance()
實例化Class
對象。
public <T> T get(Class<T> type) throws InstantiationException, IllegalAccessException {
return type.newInstance();
}
但是該類必須有一個無參數的構造函數。 可能會引發異常。
T
是類型而不是類型的占位符; 因此您不能調用new T()
因為您在T
沒有值。
該值是type
,您必須使用該變量。
重要的是要記住,在泛型系統中,占位符不是Java類型意義上的類型。 他們遵循關於如何約束它們的不同規則(超級等)。 它們在應用時(編譯時)具有不同的綁定。 這些特性意味着即使它們(在某種程度上)對其進行控制,它們也無法與Java的類型系統保持一致。
現在,您確實擁有一個Class
對象作為綁定到變量type
。 您可以使用Java的功能從type
的Class
對象創建新實例。
您可以使基類通用,因此您可以為get()
方法使用適當的返回類型。
abstract class Vehicle<T extends Vehicle> {
public abstract T get();
}
class Car extends Vehicle {
@Override
public Car get() {
return new Car();
}
}
但是,這並不強制Car
實際返回Car
; 可以免費返回Van
。
修改您的get方法,如以下代碼所示:
public <T> T get(Class<T> type) throws InstantiationException, IllegalAccessException {
return type.newInstance();
}
如果您在Car和Van類中具有默認構造函數,則可以使用以下方法:
public static <T extends Vehicle> T get(Class<T> cls) throws Exception {
return cls.getConstructor().newInstance();
}
或者,作為替代方案,這(對我來說似乎更可取;但是我與上一個沒有任何矛盾):
public static <T extends Vehicle> T get(Class<T> cls) {
if (cls.isAssignableFrom(Car.class))
return (T)new Car();
if (cls.isAssignableFrom(Van.class))
return (T)new Van();
throw new RuntimeException("Unknown class '" + cls.getSimpleName() + '\'');
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.