泛型类的类型参数声明在类名后,作用于整个类且实例化后固定;泛型方法的类型参数声明在返回类型前,仅作用于该方法,每次调用可独立推断类型。

泛型方法和泛型类的类型参数,核心区别在于**声明位置、作用域和生命周期**,不是看名字是否都叫 T,而是看它“在哪声明”“为谁服务”。
泛型类的类型参数:写在类名后面,影响整个类
它属于类的“整体设定”,一旦实例化(如 Box<string></string>),这个 T 就被固定为 String,类中所有用到 T 的地方(字段、普通方法参数/返回值)都按这个具体类型处理。
- 声明形式:
class Box<t> { ... }</t>或interface List<e> { ... }</e> - 不能在静态上下文中直接使用(因为静态成员属于类本身,不随类型参数变化)
- 类里的普通方法(比如
public T get() { ... })用的是这个已确定的T,它不是泛型方法
泛型方法的类型参数:写在返回类型前,只管当前方法
它是独立于类的,每次调用时都可以传入不同的类型实参。哪怕类本身没泛型,方法也能是泛型的;哪怕类已有 T,方法里声明的 <e></e> 或另一个 <t></t> 是全新变量,和类的 T 没关系。
- 声明形式:
public <E> void print(E item) { ... }或static <K, V> Map<K,V> of(K k, V v) { ... } - 支持静态方法,也支持实例方法
- 方法签名中必须显式写出
<...>,否则只是用了类的类型参数,不是泛型方法
关键判断口诀:看尖括号在哪,看它管多大范围
一个 T 是类的,还是方法的,不取决于字母,而取决于它的 <T> 出现在哪:
立即学习“Java免费学习笔记(深入)”;
- 如果
<T>紧跟在class或interface名字后 → 类型参数属于类/接口 - 如果
<T>紧跟在访问修饰符或static后、返回类型前 → 这是泛型方法自己的类型参数 - 同一个字母(如
T)在类和方法中同时出现,它们是两个独立变量,可能类型不同
常见混淆点提醒
下面这段代码里有三个 T,但只有一个是泛型方法的类型参数:
class Container<T> {
T data;
public T get() { return data; } // 用类的 T,不是泛型方法
public <T> void setNew(T value) { ... } // 新的 T,是泛型方法自己的参数
public <E> void show(E e) { ... } // 另一个泛型方法,E 和类 T 无关
}
调用 container.setNew("hello") 时,方法内的 T 就是 String,和 Container<Integer> 中那个 T 完全无关。


















