簡體   English   中英

Java將參數化的泛型類型作為valueType發送

[英]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.

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