在 Java 中,由于類型擦除機制,泛型信息在編譯時會被移除,導致運行時無法獲取泛型參數的具體類型。這可能會引發一些問題,例如在運行時無法確定集合中元素的類型。為了解決這個問題,可以采用以下方法:
通配符是一種表示未知類型的方式。當你需要處理未知類型的泛型對象時,可以使用通配符。例如,List<?>
表示一個未知類型的列表。通配符有兩種形式:
List<?>
,表示任意類型的列表。List<? extends T>
或 List<? super T>
,分別表示 T 類型或其子類型的列表,以及 T 類型或其父類型的列表。泛型方法允許你在方法級別上指定泛型參數。這樣,在調用方法時,編譯器會根據傳入的參數類型自動推斷泛型參數的具體類型。例如:
public <T> void printList(List<T> list) {
for (T item : list) {
System.out.println(item);
}
}
創建一個泛型類或接口,并在類或接口中定義泛型參數。這樣,在實例化泛型類或實現泛型接口時,可以為泛型參數指定具體的類型。例如:
public class GenericBox<T> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
類型令牌是一種表示泛型類型的方式。它是一個具有泛型參數的匿名子類,可以在運行時獲取泛型參數的類型信息。例如:
public class TypeToken<T> {
private final Class<? super T> rawType;
protected TypeToken() {
this.rawType = getSuperclassTypeParameter(getClass());
}
private static Class<?> getSuperclassTypeParameter(Class<?> subclass) {
// ... 獲取泛型參數的類型信息
}
public final Class<? super T> getRawType() {
return rawType;
}
}
然后,你可以使用類型令牌來獲取泛型參數的具體類型:
TypeToken<List<String>> stringListType = new TypeToken<List<String>>() {};
Class<?> rawType = stringListType.getRawType(); // 獲取原始類型
請注意,類型令牌僅適用于某些特定場景,例如 JSON 序列化和反序列化。在大多數情況下,使用通配符和泛型方法應該足夠解決類型擦除問題。