泛型类的类型参数T必须紧贴类名用尖括号包裹,如class MyClass<T>✅;泛型方法的类型参数须置于修饰符后、返回类型前,如public static <T> T getValue()✅;泛型参数只能是引用类型,不支持基本类型。

泛型类定义时 T 必须写在类名后,不能放在 class 关键字后
常见错误是把 <t></t> 写成 class<t> MyClass</t>,这会直接编译失败。Java 要求类型参数声明紧贴类名,且用尖括号包裹。
-
class MyClass<t></t>✅ 正确位置 -
class<t> MyClass</t>❌ 语法错误,class后不能接泛型参数 - 多个泛型参数用逗号分隔:
class Pair<k v></k> - 泛型参数命名习惯用单个大写字母(
T表示 Type,K/V表示 Key/Value),但不是强制,class Box<elementtype></elementtype>也合法,只是冗长
泛型方法的 <t></t> 必须写在返回类型前,且不能省略
泛型方法的类型参数声明位置容易错——它必须出现在修饰符之后、返回类型之前。漏掉或放错位置,编译器会当成普通标识符报错。
-
public static <t> T getValue()</t>✅ 正确:类型参数<t></t>在static后、T前 -
public static T getValue()❌ 编译失败:此时T是未声明的类或类型,不是泛型参数 - 静态泛型方法不能访问外围类的泛型参数(如
class Container<t></t>中的T),必须自己声明<t></t> - 如果方法返回值和参数都用同名泛型,仍需显式声明一次:
public <t> void process(T item)</t>
泛型参数不能是基本类型,int 要写成 Integer
Java 泛型擦除后只保留 Object 类型,所以所有泛型参数必须是引用类型。传 int、boolean 会直接编译报错。
-
List<int></int>❌ 错误:基本类型不支持泛型 -
List<integer></integer>✅ 正确:包装类是引用类型 - 数组类型可以作为泛型参数:
List<int></int>合法,因为int[]是引用类型 - 注意自动装箱陷阱:向
List<integer></integer>add(1) 没问题,但比较时list.get(0) == 1可能因缓存机制偶然成立,==比较的是引用,应优先用.equals()
泛型类实例化时,类型实参可省略(钻石操作符),但方法调用不能靠推断补全
Java 7+ 支持钻石操作符 省略构造器右侧的泛型参数,但这个省略只适用于构造器调用;泛型方法调用仍需显式指定或依赖类型推断,而推断有局限。
立即学习“Java免费学习笔记(深入)”;
-
new ArrayList<string>()</string>可简写为new ArrayList()✅ -
MyClass.<string>create()</string>不能简写为MyClass.create()—— 如果方法签名是static <t> T create()</t>,编译器无法从上下文推断T,可能返回Object或报错 - 当泛型方法参数含泛型类型时,推断才更可靠:
Arrays.asList("a", "b")推出List<string></string>,因为参数明确是String - 泛型擦除意味着运行时无法获取
T的真实类型,所以不能写new T()或T.class
<t></t> 在编译后就没了,所有逻辑都得绕着这个事实设计。比如想在泛型类里 new 一个 T 实例,或者判断 obj instanceof T,都不行——这些不是写法问题,是语言机制决定的。









