🧠 本质区别:一个是 对象类型(引用类型) ,一个是 基本数据类型(值类型)
| 对比点 | int(基本类型) | Integer(引用类型) |
|---|---|---|
| 类型 | 基本类型 | 包装类(对象) |
| 是否为对象 | ❌ 否 | ✅ 是 |
| 是否可为 null | ❌ 不可以,null 会报错 | ✅ 可以为 null |
| 用途 | 更节省内存、效率高 | 适合集合、泛型、反射等需要对象的场景 |
| 存储位置 | 栈上直接存储数值 | 堆上分配对象引用 |
| 示例 | int a = 1; | Integer a = 1; 或 new Integer(1) |
💡 举例说明:
int a = 1;
Integer b = 1; // 自动装箱,相当于 Integer.valueOf(1)
Integer c = null; // ✔ 合法
int d = null; // ❌ 报错:NullPointerException
📌 自动装箱与拆箱(Java 编译器自动转换):
Java 会自动在 int 和 Integer 之间进行转换:
Integer obj = 10; // int -> Integer (自动装箱)
int val = obj; // Integer -> int (自动拆箱)
下面我将详细、通俗地讲解 Java 中的 自动装箱(Autoboxing) 和 自动拆箱(Unboxing)
✳️ 一、什么是自动装箱(Autoboxing)和自动拆箱(Unboxing)?
✅ 自动装箱(Autoboxing):
Java 编译器会自动将基本数据类型(如 int)转换为对应的包装类对象(如 Integer) 。
比如:
int a = 10;
Integer b = a; // 编译器自动转换成:Integer b = Integer.valueOf(a);
✅ 自动拆箱(Unboxing):
Java 编译器会自动将包装类对象转换为基本类型。
比如:
Integer b = 10;
int a = b; // 编译器自动转换成:int a = b.intValue();
📌 这两者都是 Java 编译器从 Java 5 开始支持的语法糖,是为了解决基本类型和对象类型之间转换繁琐的问题。
✳️ 二、自动装箱和拆箱的应用场景
✅ 示例 1:赋值时
Integer num = 100; // 自动装箱:int -> Integer
int val = num; // 自动拆箱:Integer -> int
✅ 示例 2:方法参数或返回值
public static void printNum(Integer num) {
System.out.println(num);
}
printNum(5); // int 自动装箱为 Integer
✅ 示例 3:集合中只能放对象(不能放 int)
List<Integer> list = new ArrayList<>();
list.add(10); // 自动装箱:int -> Integer
int val = list.get(0); // 自动拆箱:Integer -> int
✳️ 三、装箱过程的底层机制
🎯 Integer.valueOf(int i)
Integer.valueOf()是一个静态方法,其作用是把基本数据类型int或者字符串String转换为Integer对象。
intValue()是Integer类的一个实例方法,它的功能是把Integer对象转换为基本数据类型int。
在自动装箱的时候,Java 实际上调用的是:
Integer i = Integer.valueOf(10);
注意:Integer.valueOf() 方法有缓存机制!
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true ✅
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false ❌
这是因为 Java 对 -128 到 127 之间的整数做了缓存(在 JVM 中的 IntegerCache 类中实现):
// Integer.valueOf源码:
if (i >= -128 && i <= 127) {
return IntegerCache.cache[i + 128];
} else {
return new Integer(i);
}
✳️ 四、容易踩的坑(⚠️)
❌ 1. 用 == 比较 Integer 装箱对象
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true,引用相同(缓存)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false,引用不同(未缓存)
✅ 正确写法:
System.out.println(a.equals(b)); // 推荐使用 equals 比较值
❌ 2. null 拆箱会抛异常
Integer i = null;
int j = i; // ⚠️ 报 NullPointerException
因为自动拆箱的时候,Java 背后执行的是 i.intValue(),对 null 调用方法当然会报错。
✅ 正确写法:
if (i != null) {
int j = i;
}
✳️ 五、装箱拆箱的类型对照表
| 基本类型 | 包装类 |
|---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
✅ 总结一图(高频考点)
装箱(Autoboxing) 拆箱(Unboxing)
--------------------- ------------------------
int → Integer Integer → int
long → Long Long → long
boolean → Boolean Boolean → boolean
...
-
✅ 用于简化基本类型与对象类型之间的转换
-
⚠️ 注意缓存范围:
[-128, 127] -
⚠️ 拆箱 null 会抛异常
-
❗ 避免使用
==比较两个装箱对象