Java泛型方法通过显式声明类型变量(如<T>)实现类型安全的通用逻辑,要求类型变量出现在参数或返回值中,并可用extends约束能力(如T extends Comparable),通配符则提升集合参数灵活性。

Java 中方法配合泛型实现通用类型的数据处理,关键在于把“类型”变成可推断、可约束的参数,让同一段逻辑能安全适配 String、Integer、User 等不同类,同时编译器全程把关——不是靠运行时 try-catch,而是写错就报红。
泛型方法定义要带 声明
方法签名前必须显式声明类型变量,比如 public static
- 类型变量通常用单个大写字母:T(Type)、E(Element)、K/V(Key/Value)
- 多个类型可并列:
Map toMap(List keys, List values) - 类型变量必须出现在参数或返回值中,否则无法推断——
void log() 这种写法无效
用边界(extends)约束能力范围
如果方法里要调用 .compareTo() 或 .doubleValue(),就不能只写
-
public static
> T max(T[] arr) —— T 必须实现 Comparable,才能调用 item.compareTo() -
public static
double sum(List —— 可调用 .doubleValue(),支持 Integer、Double、BigDecimalnums) - 多个上界用 & 连接:
,表示 T 必须同时满足两者
接收集合时善用通配符
方法参数别死锁在某个具体泛型类型上。想读取 List 中所有元素?用 extends T>;想往里塞数据?用 super T>:
立即学习“Java免费学习笔记(深入)”;
-
void printNames(List extends Person> people):能传入 List
或 List ,因为它们都是 Person 子类,安全读取 -
void addInts(Collection super Integer> target):能接受 Collection
或 Collection - 避免写 List 或 List——前者太宽泛,后者失去类型检查
避开类型擦除带来的坑
泛型只在编译期存在,运行时 T 已变成 Object 或上界类型。所以这些事不能做:
- ❌ if (obj instanceof T) —— 编译不过,T 擦除后不存在
- ❌ new T[10] —— 数组创建需要运行时类型,改用 (T[]) new Object[10](需加 @SuppressWarnings("unchecked"))或传入 Class
- ❌ 在静态方法/字段里直接用类级泛型参数(如 static T DEFAULT)——静态属于类,泛型属于实例,二者不搭
- ✅ 替代方案:传 Class
对象,用 clazz.cast(obj) 或 clazz.getDeclaredConstructor().newInstance()
基本类型数组需单独处理
泛型方法
- 正确做法:为基本类型写重载方法,比如 void print(int[] arr)、void print(double[] arr)
- 不要试图用 Object[] 强转:int[] 和 Object[] 是完全不同的 JVM 类型,强转会 ClassCastException
- 打印时统一用 Arrays.toString(arr),它内部已区分基本类型和引用类型数组


















