簡體   English   中英

創建給定Class類型的實例

[英]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的功能從typeClass對象創建新實例。

您可以使基類通用,因此您可以為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM