[英]Java send parameterized generic type as valueType
我有一個方法,它返回給定的類型:
T foo(Class<T> valueType) {...};
String s = foo(Java.lang.String.class);
我正在嘗試將通用類型作為類發送,但遇到編譯器錯誤。 例如,假設我要返回字符串的ArrayList:
ArrayList<String> list = foot(ArrayList<String>.class)
參數“字符串”給出錯誤。 無論如何,我可以指定要返回的通用類型嗎?
運行時class
字段值不取決於您應用的泛型類型,並且此語法是非法的。 更多關於這里 。
這對您有用嗎(編輯)?
ArrayList list = foot(ArrayList.class)
只需轉換方法的輸入或輸出即可:
ArrayList<String> list = foot((Class<ArrayList<String>>)(Class<?>)ArrayList.class);
要么
ArrayList<String> list = (ArrayList<String>)foot(ArrayList.class);
基本上, Class
類不適用於泛型,因為它表示運行時事物,而泛型在編譯時起作用。 在運行時,程序中只有一個ArrayList
類對象。 即使您將其稱為Class<ArrayList<String>>
或Class<ArrayList<Integer>>
或Class<ArrayList>
,它仍然是同一個對象。 那應該是什么類型呢? 沒有簡單的答案可適用於所有情況。
Java語言決定類文字ArrayList.class
的類型應為Class<ArrayList>
。 但是,當您想要類型為Class<ArrayList<String>>
的表達式時,這會導致問題,因此您必須彎曲類型。
假設您在這里只關心靜態類型,此技巧可能會很有用:
@SuppressWarnings("unchecked")
public static <T>
Class<T> appropriateClass(T... args) {
return (Class<T>) args.getClass().getComponentType();
}
Class<ArrayList<String>> c = appropriateClass();
ArrayList<String> list = foo(c);
實際上,我對這個技巧並不感到驕傲。 但是您可能想嘗試一下。
如果您測試它:
System.out.println(c); // prints "class java.util.ArrayList"
因此,它等效於丑陋的類型轉換,例如(Class<ArrayList<String>>) (Class<?>) ArrayList.class
。
如果實際上在運行時需要ArrayList<String>
和ArrayList
令牌不同,則應使用Sean Patrick Floyd提到的TypeToken
技術。
Type Erasure抬起丑陋的頭。 本質上,Java對通用<…>
子句進行編譯時檢查,然后從運行時對象中刪除它們,從而永遠丟失信息。 討厭吧? 由於.class
元對象是在運行時引用的,因此它們也會受到擦除的影響。
ArrayList<String>.class
在編譯時被擦除,成為ArrayList.class
。
如果要使用泛型進行類型安全,則必須傳入兩個參數,例如
ArrayList<String> foo = foot(ArrayList.class, String.class)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.