簡體   English   中英

在Java中的超類的構造函數中獲取擴展的泛型類的泛型類型?

[英]Get the generic type of an extending generic class in the constructor of the superclass in Java?

我有一個abstract class Abstr<T>和一個擴展class Ext<T> 我需要Abstr知道,擴展名是使用哪個T初始化的,因此它可以返回該類型。 到目前為止,我已經通過將類型提供給構造函數,然后調用超構造函數進行保存來完成此操作。 但是我認為這也應該與反思一起起作用。 到目前為止,就像我說的:

public abstract class Abstr<T> {

    private Class<T> type;

    public Abstr(Class<T> _class) {
        this.type = _class;
    }

}

public class Ext<T> extends Abstr<T> {

    public Ext(Class<T> _class) {
        super(_class);
    }

}

public void someMethod() {
    Ext<String> ext = new Ext<String>(String.class);
}

使用反射應該讓我擺脫調用任何構造函數的麻煩,因為擴展的默認構造函數將調用抽象類的默認構造函數,然后應保存調用構造函數的類型:

public Abstr() {    
    this.type = (Class<D>) this.getClass().getTheTypeParameter(); // something along these lines
}

謝謝!

唯一可行的情況是當您具有帶有泛型父級的非泛型類時。 一個例子是

class Trick<T> {
    T t;
}

public class GenericTest {
    public static void main(String[] args) {
        Trick<Set<String>> trick = new Trick<Set<String>>() {
        };

        // Prints "class org.acm.afilippov.GenericTest$1"
        System.out.println(trick.getClass());
        // Prints "org.acm.afilippov.Trick<java.util.Set<java.lang.String>>"
        System.out.println(trick.getClass().getGenericSuperclass());
    }
}

要進一步閱讀,請參閱Reflecting Generics教程-答案已經存在,但是引用它的時間太長了,感覺好像我在偷代碼。 所以請在那里閱讀:)

這可能並不總是有效,因為如果您在某些方法中僅具有new Ext<String>() ,則該類型將沒有反射數據。

因此Ext<String> ext = new Ext<String>(String.class); 將在運行時(類型擦除)有效地釋放類型信息,從而導致Ext ext = new Ext(String.class);

如果您有private Ext<String> stringExt類的private Ext<String> stringExt或者StringExt extends Ext<String>類的具體子類,則可以獲取反射數據。

這是一篇簡短的文章,其中包含一些源代碼,可用於獲取具體子類(甚至可能用於字段)的反射數據: http : //www.artima.com/weblogs/viewpost.jsp?thread = 208860

正如我所說,我們正在使用該代碼的調整版本來獲取具體子類的類型參數。

所以我們有這樣的事情:

class AbstractDAO<T entityType> {
  protected Class<?> entityClass;

  protected AbstractDAO() {
    //ReflectionUtil is our adjusted version of code in the link above
    entityClass = ReflectionUtil.getTypeArguments(AbstractDAO.class, getClass() ).get(0);
  }
}

//Here entityClass is User.class
class UserDAO extends AbstractDAO<User> { ... }

如果您確實需要Abstr類似的方法

public Class<T> getType()

您別無選擇,只能在構造函數(或任何其他方法)中傳遞Class相等性。 由於類型Erase ,您無法檢索TClass ,這基本上歸結為T在運行時僅在編譯時不可用的事實。

Abstr的通用類型為T您可以通過反射獲得所有這些。

如果您想簡化代碼,可以編寫。

public class Ext<T> extends Abstr<T> {
    protected Ext(Class<T> _class) {
        super(_class);
    }

    public static <T> Ext<T> of(Class<T> _class) { return new Exit<T>(_class); }
}

Ext<String> ext = Ext.of(String.class);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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