包装类是为解决基本类型非对象化问题而设的适配桥梁,核心在于自动装箱/拆箱的空指针与缓存陷阱(-128~127)、比较须用equals()、valueOf优于new、parseInt不创建对象、泛型强制使用包装类。

直接读核心机制和高频陷阱,别从头翻源码。
搞懂包装类存在的根本原因
Java 是面向对象语言,但基本类型(int、boolean 等)不是对象,没法直接用于泛型、集合、反射或统一接口处理。包装类(Integer、Boolean 等)就是为了解决这个“对象化”需求而生的桥梁。
重点理解:它们不是“替代”,而是“适配”——底层仍用基本类型存储,只是加了对象外壳和工具方法。
死磕自动装箱/拆箱的边界条件
这是面试必问点,关键不在语法,而在隐式转换引发的空指针和缓存陷阱:
立即学习“Java免费学习笔记(深入)”;
- 拆箱时如果包装类引用为 null,会直接抛 NullPointerException(比如
Integer i = null; int j = i;) - Integer 在 -128 到 127 范围内用的是缓存对象,所以
Integer a = 100; Integer b = 100; a == b为 true;但Integer c = 200; Integer d = 200; c == d为 false(new 出的不同对象) - 比较务必用 equals(),尤其涉及可能为 null 的变量;== 只适合确定非 null 且在缓存范围内的 Integer
看清常用方法的设计意图
不是背 API,而是理解为什么这样设计:
-
Integer.valueOf(String)比new Integer(String)更优——复用缓存,避免无谓对象创建 -
parseInt(String)返回基本类型 int,不产生对象,适合纯数值计算场景 -
toString(int)是静态工具方法,和包装类实例无关,别误以为是实例方法
警惕泛型擦除带来的包装类表现
泛型在运行时被擦除,但 Collection 等容器实际只能存对象。所以 List<int></int> 合法语法都不允许,必须写 List<integer></integer> —— 这不是风格选择,是 JVM 类型系统的硬性约束。
由此引申:lambda 表达式里对包装类的操作(如 list.stream().mapToInt(Integer::intValue))本质是在做显式拆箱,性能敏感场景需留意装箱开销。


















