在 Java 開發中,原生態類型指的是未帶類型參數的泛型類或介面(如 List 而非 List<String>)。雖然為了向後兼容 Java 允許使用原生態類型,但這會嚴重削弱類型安全,導致運行時才拋出 ClassCastException,而非編譯期捕獲錯誤。
public class RawTypeDemo {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
unsafeAdd(strings, Integer.valueOf(42)); // 編譯器只會警告
String s = strings.get(0); // 運行時拋出 ClassCastException
}
private static void unsafeAdd(List list, Object o) {
list.add(o);
}
}
若將參數改為 List<Object>,IDE 會直接報錯,因為 List<String> 不是 List<Object> 的子類型。這正是泛型的不變性所帶來的保護。
當不關心集合元素的具體類型時,應使用 Set<?> 而非原生態 Set。兩者的關鍵區別在於:
null 外,不可插入任何元素,編譯器保證類型安全。// 推薦寫法:使用無限制通配符
static int numElementsInCommon(Set<?> s1, Set<?> s2) {
int result = 0;
for (Object o : s1) {
if (s2.contains(o)) result++;
}
return result;
}
List.class、String[].class,不能用 List<String>.class。if (obj instanceof Set<String>) 非法。正確做法是:
if (obj instanceof Set) {
Set<?> s = (Set<?>) obj; // 必須轉為通配符類型,而非原生態
}
原生態類型是為了兼容舊代碼而存在的「妥協產物」。在新代碼中,請堅持使用參數化類型或無限制通配符,讓編譯器為你把關,將潛在的運行時錯誤提前到編譯期發現。