java泛型类通过在类名后加等类型参数实现类型可变,实例化时传入具体类型如box,编译期检查类型安全,运行时擦除泛型信息,不支持基本类型和泛型数组。

Java 中定义泛型类,核心是把类型当作参数来声明和使用,不是写死某个具体类型,而是在类名后加一对尖括号 <t></t>(或多个如 <k v></k>),然后在类体中用这个符号代表类型。传递类型参数发生在创建对象时,比如 new Box<string>()</string> —— 这里的 String 就是传入的具体类型实参。
泛型类的基本定义格式
在类声明时,在类名后加上类型形参(如 T、E、K、V 是常用约定),之后可在字段、方法参数、返回值、局部变量中直接使用该符号:
-
单类型参数:
public class Box<t> { private T content; public void set(T content) { this.content = content; } public T get() { return content; } }</t> -
多类型参数:
public class Pair<k v> { private K key; private V value; }</k> -
带边界限制:
public class NumberBox<t extends number> { private T value; }</t>(只能传Integer、Double等Number子类)
实例化时传入具体类型
使用泛型类时,必须指定实际类型(类型实参),编译器据此做类型检查和自动推导:
-
Box<string> stringBox = new Box();</string>→content只能存String,get()返回String,无需强转 -
Box<integer> intBox = new Box();</integer>→ 类型安全,若误写intBox.set("abc"),编译直接报错 - 注意:不能用基本类型(如
int),必须用包装类(Integer)
泛型的类型擦除特性
Java 泛型只在编译期生效,运行时会擦除所有类型信息(即变成原始类型,如 Box<string></string> 和 Box<integer></integer> 运行时都是 Box)。这意味着:
- 无法在运行时通过
instanceof判断泛型类型,例如if (obj instanceof Box<string>)</string>是非法语法 - 静态方法/字段不能直接引用类的类型参数(因为静态内容属于类本身,不随类型参数变化)
- 构造器、普通方法中可以正常使用类型参数,它们依赖于实例的类型实参
常见误用与提醒
初学者容易踩的几个坑:
- 不要写
new ArrayList<t>()</t>在泛型类内部——T已被擦除,得用new ArrayList<object>()</object>或借助反射(但通常不推荐) - 不能创建泛型数组:
new List<string>[10]</string>编译失败;可改用List<string>[] array = (List<string>[]) new List[10];</string></string>(需抑制警告) - 子类继承泛型类时,可选择固定类型(
class StringBox extends Box<string></string>)或继续泛型化(class GenericBox<t> extends Box<t></t></t>)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











