Java基本类型不能作泛型参数,因类型擦除要求原始类型为引用类型;须用Integer等包装类替代,并注意自动装箱、缓存陷阱及==比较风险,泛型方法中需通过Number等上界配合拆箱操作。

Java 中基本类型(如 int、boolean)不能直接作为泛型参数,是因为泛型在编译期会进行类型擦除,而擦除后的原始类型必须是引用类型——基本类型不继承 Object,无法参与泛型体系。解决这一限制的核心路径,就是通过包装类“桥接”基本类型与泛型机制。
用包装类替代基本类型作为泛型实参
所有集合类(如 ArrayList、HashMap)和自定义泛型结构都只接受引用类型。因此,需将基本类型显式或隐式转为对应包装类:
-
ArrayList<Integer>✅ 合法:Integer是int的包装类,属于引用类型 -
ArrayList<int>❌ 编译报错:基本类型不能作为泛型参数 - 实际使用中可依赖自动装箱简化写法:
list.add(100)等价于list.add(Integer.valueOf(100))
注意 Integer 等缓存带来的陷阱
包装类对象不是简单等价于基本值,尤其在使用 == 比较时容易出错:
-
Integer a = 127, b = 127;→a == b为 true(缓存池 -128 ~ 127 内复用同一对象) -
Integer c = 128, d = 128;→c == d为 false(超出缓存范围,新建不同对象) - 安全比较应统一用
.equals()或先拆箱再比:a.intValue() == b.intValue()
泛型方法中支持基本类型输入的写法
泛型方法本身不接受基本类型形参,但可通过包装类+自动拆箱实现“透明支持”:
- 定义
<T extends Number> T add(T a, T b),调用时传入Integer、Double均可 - 内部运算需手动拆箱:
a.doubleValue() + b.doubleValue() - 避免在泛型约束中写
T extends int—— 语法非法,int不是类,不能作上界
绕过类型擦除获取运行时类型信息(进阶场景)
当需要在运行时识别泛型具体类型(例如 JSON 反序列化),仅靠泛型声明不够,需结合包装类的 Class 对象:
- 显式传入
Class<Integer>:如fromJson(json, Integer.class) - 利用匿名子类捕获泛型(如
new TypeToken<List<String>>(){}),底层仍依赖String.class这类具体引用类型的元数据 - 基本类型无
.class字段(int.class是Integer.TYPE,非Integer.class),所以必须用包装类类型来承载

















