1. 本质区别
特性 | int | Integer |
---|---|---|
类型 | 基本数据类型(Primitive) | 包装类(Wrapper Class) |
存储位置 | 栈(或作为对象成员在堆中) | 堆(对象实例) |
默认值 | 0 | null(可能导致 NullPointerException ) |
内存占用 | 4 字节 | 约 16 字节(对象头 + 内部 int 值) |
2. 核心区别解析
(1) 基本类型 vs 包装类
-
int:Java 的 8 种基本数据类型之一,直接存储数值,性能高。
-
Integer:对
int
的封装类,属于对象类型,提供面向对象的方法(如compareTo()
、toString()
)。
(2) 自动装箱(Autoboxing)与拆箱(Unboxing)
Java 编译器在编译期自动完成基本类型与包装类的转换:
// 自动装箱:int → Integer
Integer a = 100; // 实际调用 Integer.valueOf(100)// 自动拆箱:Integer → int
int b = a; // 实际调用 a.intValue()
(3) 缓存机制(Integer Cache)
-
范围:-128 ~ 127(可通过
-XX:AutoBoxCacheMax
调整上限)。 -
原理:在此范围内的
Integer
对象会被缓存,复用同一对象。Integer x = 127; Integer y = 127; System.out.println(x == y); // true(同一对象)Integer m = 128; Integer n = 128; System.out.println(m == n); // false(新对象)
(4) 比较陷阱
Integer a = 200;
Integer b = 200;// 错误:比较对象地址
System.out.println(a == b); // false
// 正确:比较数值
System.out.println(a.equals(b)); // true
System.out.println(a.intValue() == b); // true
3. 使用场景对比
场景 | 推荐类型 | 原因 |
---|---|---|
计算密集型操作 | int | 避免自动装箱/拆箱开销,提升性能 |
集合类(如 List) | Integer | 集合只能存储对象类型(如 List<Integer> ,无法使用 List<int> ) |
数据库映射 | Integer | 数据库字段可能为 NULL,需用包装类表示空值 |
JSON 序列化 | Integer | 兼容 null 值,避免反序列化时因缺失字段导致默认值问题 |
4. 常见问题与陷阱
(1) NullPointerException
Integer count = null;
int total = count; // 自动拆箱抛出 NullPointerException
(2) 性能损耗
// 循环内频繁装箱拆箱导致性能下降
long start = System.currentTimeMillis();
Integer sum = 0;
for (int i = 0; i < 1_000_000; i++) {sum += i; // 等价于 sum = Integer.valueOf(sum.intValue() + i)
}
System.out.println("耗时:" + (System.currentTimeMillis() - start) + "ms");
// 输出:耗时约 15ms(int 版本仅需 1ms)
(3) 等值比较错误
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false(超出缓存范围,地址不同)
5. 总结与最佳实践
-
优先使用 int:在无需表示
null
的高性能场景(如循环、数学运算)。 -
必须使用 Integer:集合存储、数据库映射、API 接口设计(兼容空值)。
-
注意事项:
-
比较包装类时始终使用
equals()
或手动拆箱。 -
警惕自动装箱的性能损耗,避免在循环中频繁使用。
-
理解缓存机制,避免超出范围的对象重复创建。
-