一、基本概念
项目 | int |
Integer |
---|---|---|
类型 | 基本数据类型(primitive type) | 包装类(wrapper class) |
所属 | Java 语言内置 | java.lang.Integer 类 |
继承关系 | 无 | 继承自 Number ,实现 Comparable |
默认值 | 0 |
null (引用类型) |
二、核心区别对比表
特性 | int |
Integer |
---|---|---|
类型 | 基本类型 | 引用类型(对象) |
存储位置 | 栈(局部变量)或方法区 | 堆(对象) |
默认值 | 0 |
null |
可为 null | ❌ 否 | ✅ 是 |
内存占用 | 4 字节 | 至少 16 字节(对象头 + value) |
性能 | ⭐⭐⭐⭐⭐(快) | ⭐⭐⭐(慢,有装箱/拆箱开销) |
适用场景 | 计算、循环、高频操作 | 集合、泛型、反射、null 判断 |
方法支持 | 无 | 丰富(toString , bitCount , decode 等) |
三、详细对比说明
1. 类型与存储
int
是基本类型,直接存储数值。Integer
是对象引用,指向堆中一个Integer
对象。
int a = 100; // 直接在栈中存储 100
Integer b = 100; // b 是引用,指向堆中 new Integer(100)
2. 默认值与 null
public class Test {
static int x; // 默认值:0
static Integer y; // 默认值:null
public static void main(String[] args) {
System.out.println(x); // 输出:0
System.out.println(y); // 输出:null
}
}
✅
Integer
可用于表示“未初始化”或“无值”状态,int
不能。
3. 自动装箱(Autoboxing)与拆箱(Unboxing)
Java 5 引入了自动装箱/拆箱机制,简化了 int
与 Integer
的转换。
✅ 自动装箱:int → Integer
int a = 42;
Integer b = a; // 自动装箱:等价于 Integer.valueOf(a)
✅ 自动拆箱:Integer → int
Integer c = Integer.valueOf(100);
int d = c; // 自动拆箱:等价于 c.intValue()
⚠️ 注意空指针异常(NPE)
Integer x = null;
int y = x; // 抛出 NullPointerException!
4. 缓存机制(Integer Cache)
Integer.valueOf(int)
方法使用了缓存池优化:
- 范围:
-128
到127
(可配置) - 相同值的
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(c.equals(d)); // true(值相等)
✅ 推荐使用
equals()
比较Integer
值是否相等,避免==
陷阱。
5. 性能对比
操作 | int |
Integer |
---|---|---|
赋值 | 极快 | 较慢(可能创建对象) |
运算 | 极快 | 慢(拆箱 → 运算 → 装箱) |
存储 | 4 字节 | 至少 16 字节 |
GC 压力 | 无 | 有(对象需回收) |
✅ 结论:在高频计算、循环、数组等场景,优先使用 int
。
四、使用场景推荐
✅ 推荐使用 int
的场景
- 数学计算、算法实现
- 循环计数器
- 数组元素(
int[]
) - 性能敏感代码
- 不需要
null
语义
for (int i = 0; i < 1000; i++) { ... } // 推荐
✅ 推荐使用 Integer
的场景
- 集合类(
List<Integer>
,Map<String, Integer>
) - 泛型(
T extends Number
) - 反射(
Method.invoke()
返回Object
) - 需要
null
表示“无值” - 作为方法参数允许不传值
- 使用
Optional<Integer>
List<Integer> numbers = new ArrayList<>(); // 必须用 Integer
Map<String, Integer> scores = new HashMap<>();
五、常见误区与陷阱
❌ 误区 1:==
比较 Integer
Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false!
System.out.println(a.equals(b)); // true
✅ 正确做法:比较值用 equals()
,比较引用才用 ==
。
❌ 误区 2:在循环中频繁装箱
// ❌ 性能差
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
list.add(i); // 每次自动装箱
}
✅ 优化:若非必要,避免在高频循环中创建 Integer
。
❌ 误区 3:忽略 null
导致 NPE
public int process(Integer value) {
return value * 2; // 可能抛 NPE
}
✅ 防御性编程:
public int process(Integer value) {
return (value != null) ? value * 2 : 0;
}
六、转换方法总结
转换方向 | 方法 |
---|---|
int → Integer |
Integer.valueOf(int) (推荐)、自动装箱 |
Integer → int |
integer.intValue() 、自动拆箱 |
String → int |
Integer.parseInt(str) |
String → Integer |
Integer.valueOf(str) |
int → String |
String.valueOf(i) 、Integer.toString(i) |
七、一句话总结
int
是高效的基础类型,用于计算;Integer
是灵活的包装对象,用于集合与泛型。理解自动装箱/拆箱与缓存机制,避免==
陷阱和 NPE,是正确使用二者的关键。