背景与动机
Java 里有两套“值类型”:
- 基本类型:
int、double、boolean这类直接存值的类型 - 包装类型:
Integer、Double、Boolean这类把基本值包装成对象的类型
包装类型存在的核心原因,是很多 Java API 和集合框架只能操作对象,不能直接操作基本类型。
核心原理拆解
1. 基本类型和包装类型的对应关系
常见对应关系如下:
byte->Byteshort->Shortint->Integerlong->Longfloat->Floatdouble->Doublechar->Characterboolean->Boolean
int n = 10;Integer boxed = Integer.valueOf(n);2. 为什么集合里要用包装类型
List<Integer> numbers = new ArrayList<>();numbers.add(1);numbers.add(2);List<int> 这种写法是不行的,因为泛型参数必须是引用类型。也正因为这样,集合里经常会看到 Integer、Long 这类包装类型。
3. 自动装箱和自动拆箱
Java 会在很多场景下自动帮我们完成“基本类型 <-> 包装类型”的转换:
Integer a = 10; // 自动装箱int b = a; // 自动拆箱这让代码更简洁,但也埋下了一些坑,尤其是 null 拆箱问题。
4. 包装类型可以为 null
这是它和基本类型非常重要的区别:
Integer a = null;int b = 0;- 基本类型不能为
null - 包装类型是对象引用,所以可以为
null
这在数据库字段、接口参数、可选值场景里很常见。
5. 常用转换方法
包装类型不仅是“包了一层对象”,还提供了一些常用工具方法。
int n = Integer.parseInt("123");String s = Integer.toString(123);double d = Double.parseDouble("3.14");这些方法在字符串转数字、配置读取、接口参数解析时很常见。
6. Integer 比较要小心
Integer a = 100;Integer b = 100;System.out.println(a == b); // true
Integer x = 200;Integer y = 200;System.out.println(x == y); // false这是因为 Integer 对部分小整数有缓存机制。比较包装类型数值内容时,优先用 equals,不要依赖 ==。
最小可运行代码示例
import java.util.ArrayList;import java.util.List;
public class WrapperDemo { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); numbers.add(1); numbers.add(2);
Integer boxed = 10; int unboxed = boxed;
int parsed = Integer.parseInt("123");
System.out.println(numbers); System.out.println(unboxed); System.out.println(parsed); System.out.println(Integer.valueOf(100).equals(Integer.valueOf(100))); }}常见陷阱与错误示例
1. 对 null 包装类型自动拆箱
Integer count = null;int n = count; // NullPointerException只要发生自动拆箱,null 就可能触发空指针。
2. 用 == 比较包装类型数值
== 比较的是引用,不是数值内容。包装类型比较数值大小或内容相等,优先用 equals。
3. 误以为包装类型和基本类型完全一样
它们在默认值、是否可空、集合泛型支持、性能开销上都不一样,不能简单等同。
面试高频问题
1. 为什么 Java 需要包装类型
因为很多 API、集合和泛型只能处理对象,不能直接处理基本类型,所以需要用包装类型把基本值包装成对象。
2. 什么是自动装箱和自动拆箱
自动装箱是基本类型自动转换成包装类型,自动拆箱是包装类型自动转换成基本类型。
3. 为什么 Integer 比较常建议用 equals
因为 == 比较的是引用地址,而 Integer 还有缓存机制,导致不同数值区间的 == 结果可能不一致,用 equals 更稳定。
一句话总结
包装类型解决了“基本类型不能当对象用”的问题,但也带来了 null、拆箱和引用比较这些额外注意点。