
泛型是Java 5引入的重要特性但很多人只停留在ListString的层面。为什么不能new T[]为什么ListString不能赋值给ListObject? extends和? super何时用本文带你彻底搞懂Java泛型。一、为什么需要泛型没有泛型时集合只能存Object取出需强转容易ClassCastException。java复制下载List list new ArrayList(); list.add(hello); list.add(1); String s (String) list.get(1); // 运行时异常泛型把类型检查提前到编译期java复制下载ListString list new ArrayList(); list.add(hello); // list.add(1); // 编译报错 String s list.get(0); // 无需强转二、类型擦除Java泛型是伪泛型编译后类型参数被擦除。java复制下载ListString a new ArrayList(); ListInteger b new ArrayList(); System.out.println(a.getClass() b.getClass()); // true擦除规则无边界擦除为ObjectT extends Number擦除为Number编译期插入强制转换java复制下载// 编译前 ListString list new ArrayList(); list.add(hello); String s list.get(0); // 编译后 List list new ArrayList(); list.add(hello); String s (String) list.get(0);三、类型擦除带来的限制java复制下载// 1. 不能new泛型数组 // T[] arr new T[10]; // 编译错误 T[] arr (T[]) new Object[10]; // 需强转 // 2. 不能用于instanceof // if (obj instanceof ListString) {} // 编译错误 if (obj instanceof List) {} // 3. 不能定义泛型静态字段 // private static T instance; // 编译错误 // 4. 泛型方法重载冲突 // void method(ListString l) {} // void method(ListInteger l) {} // 编译错误擦除后相同四、通配符4.1 无界通配符java复制下载List? list new ArrayListString(); // list.add(a); // 编译错误只能读 Object o list.get(0); // 可以读4.2 上界通配符? extendsjava复制下载List? extends Number list new ArrayListInteger(); Number n list.get(0); // 可以读 // list.add(1); // 编译错误不能写4.3 下界通配符? superjava复制下载List? super Integer list new ArrayListNumber(); list.add(1); // 可以写 Object o list.get(0); // 只能读成Object五、PECS原则Producer Extends, Consumer Super生产者只读用extends消费者只写用superjava复制下载// 生产者从src读 public static T void copy(List? super T dest, List? extends T src) { for (T t : src) { dest.add(t); } } ListNumber dest new ArrayList(); ListInteger src List.of(1, 2, 3); copy(dest, src);六、泛型类与泛型方法java复制下载// 泛型类 public class BoxT { private T value; public void set(T value) { this.value value; } public T get() { return value; } } // 泛型方法 public static T extends ComparableT T max(T a, T b) { return a.compareTo(b) 0 ? a : b; } // 多边界 public static T extends Number ComparableT void sort(ListT list) { Collections.sort(list); }七、泛型与继承java复制下载// 泛型不可变 ListObject a new ArrayListString(); // 编译错误 // 但数组是协变的 Object[] arr new String[10]; // 编译通过运行时可能异常八、实战通用Result封装java复制下载public class ResultT { private int code; private String message; private T data; public static T ResultT success(T data) { ResultT r new Result(); r.code 0; r.message success; r.data data; return r; } public static T ResultT error(int code, String msg) { ResultT r new Result(); r.code code; r.message msg; return r; } } // 使用 ResultUser r Result.success(new User()); ResultListUser list Result.success(users);九、总结理解类型擦除是掌握泛型的关键。记住PECS原则生产者用extends消费者用super。泛型提升了类型安全但受擦除限制不能new数组、不能用instanceof。