ArrayList<E>:泛型類型E:類型參數ArrayList<Integer>:參數化類型Integer:實際類型參數ArrayList:原始類型泛型僅存在於**編譯期**,執行期 JVM 移除泛型資訊。
List<String> ls = new ArrayList<>();
List<Integer> li = new ArrayList<>();
System.out.println(ls.getClass() == li.getClass()); // true
可利用反射繞過編譯檢查 (不建議生產使用):
li.getClass().getMethod("add", Object.class).invoke(li, "string"); // 成功添加 String 到 List
| 語法 | 含義 | 適用場景 |
|---|---|---|
<?> | 無界通配符,任意類型 | 只呼叫與類型無關方法 (如 size、clear) |
<? extends Number> | 上界:Number 或其子類 | 讀取資料 (只能取出 Number),不可寫入 (除 null) |
<? super Integer> | 下界:Integer 或其父類 | 寫入資料 (可放入 Integer),讀取只能當 Object |
<T> void printCollection(Collection<T> c, T extra) {
for (T t : c) System.out.println(t);
c.add(extra);
}
<T> void fillArray(T[] arr, T val) {
Arrays.fill(arr, val);
}
<T> T autoConvert(Object obj) {
return (T) obj; // 編譯期無檢查,執行期可能 ClassCastException
}
public class GenericDao<T> {
public void add(T t) { System.out.println(t.getClass()); }
public T findById(int id) { return null; }
// 靜態方法不能使用類別的類型參數 T
// public static void error(T t) {} // 編譯錯誤
// 但可定義獨立泛型靜態方法
public static <E> void staticMethod(E e) {}
}
使用:GenericDao<Date> dao = new GenericDao<>(); dao.add(new Date()); 此時 findById 回傳 Date,強制轉 String 會編譯報錯,保證類型安全。