簡體   English   中英

在運行時獲取泛型類不起作用

[英]Get generic type of class at runtime is not working

我有兩個類和一個接口

public class ExcelReader<T> extends Reader<T> implements RowColumnReader<T> {

    // private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};
    // private final Type type = typeToken.getType(); 
    /* public Type getType() {
        return type;
        }*/
    // Useing Guava getting System.out.println(reader.getType()) T as ouput

        @Override
        public List<T> readFile(String file) {
          //my code
        }
    }
public abstract class Reader<T> {
    protected Class<T> clazz;

    /*public Reader() {
        clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }*/
    // Constructor is commented beacuse getting Exception java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
}

public interface RowColumnReader<T> extends HeaderFields<T>{

    public List<T> readFile(String file);
}

public interface HeaderFields<T> {

    default List<String> getHeader(Class<T> clazz) throws HeaderNotDefiendException {
        //my code
        return headerList;
    }

}

我已經嘗試了所有可能的方法來獲得泛型類。 在運行時跟隨了Get泛型類,甚至嘗試了該頁面中給出的所有解決方案。 但仍然沒有運氣。

即使有高瓦

https://stackoverflow.com/a/19775924/2290078得到getType()的輸出是T不是實際的泛型類

我的測試代碼是

Reader<Test> reader = new ExcelReader<>();
//System.out.println(reader.getType());  ---> output is T 
List<Test> list = reader.readFile("Sample.xlsx");
System.out.println(list);

這不僅僅是“我應該使用什么API來在運行時獲取泛型類型?”。 這取決於你想用泛型類型( T )做什么。

泛型更多的是編譯時檢查功能,可以使用T extendsT super強加一些有用的限制。 而已。 這可能是有用的區別<? 超級T>和<? 在Java中擴展T>

如果你想在運行時知道類型T並使用像switch這樣的東西來執行條件實現,那么你聲明泛型的類並不是真正的泛型類,因為不同類型的實現不同,因此它沒有得到優雅的支持。

我已經嘗試了所有可能的方法來獲得泛型類。

您在此處找到的這種方式無法檢索通用:

public Reader() {
    clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

因為它靜態檢索在Reader的直接超類中定義的參數化類型,在本例中是Object

在子類構造函數中移動此代碼也不起作用:

public ExcelReader() {
    clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

因為它靜態檢索Reader類中定義的參數化類型,即T 由於T沒有任何綁定,您仍然可以將Object類作為返回的類。

哪種解決方案適用於您的情況?

編譯后會刪除泛型。 所以要注意運行時使用的參數化類型信息是Test

Reader<Test> reader = new ExcelReader<>();

你必須在實際代碼中明確地“傳遞”代表泛型的Class
為此,在構造函數中添加一個表示泛型類型的Class參數,並將其存儲在字段中。 現在,您可以在運行時引用該類型。

public class ExcelReader<T> extends Reader<T> implements RowColumnReader<T> {

   private Class<T> genericType;

   public ExcelReader(Class<T> genericType){
       this.genericType = genericType;
   }
   /*...*/
}

現在,您可以通過以下方式實例化ExcelReader

ExcelReader<Test> excelReader = new ExcelReader<>(Test.class);

暫無
暫無

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

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