1. 本质与存储方式
特性 | int | Integer |
---|---|---|
类型 | 基本数据类型(Primitive Type) | 引用类型(包装类,Object 的子类) |
存储位置 | 栈内存(Stack) | 堆内存(Heap) |
内存占用 | 4 字节(固定) | 对象头 + 4 字节值 ≈ 16-24 字节 |
示例:
int a = 10; // 栈中直接存储值 10
Integer b = Integer.valueOf(10); // 堆中存储对象,变量 b 存储对象引用
2. 默认值
场景 | int | Integer |
---|---|---|
未初始化值 | 0 | null |
集合存储 | 无法直接存入集合(需自动装箱为 Integer ) | 可直接存入集合(如 List<Integer> ) |
示例:
int num1; // 默认值为 0
Integer num2; // 默认值为 null(可能引发 NullPointerException)
List<Integer> list = new ArrayList<>();
list.add(10); // 自动装箱:int → Integer
3. 功能与方法
能力 | int | Integer |
---|---|---|
方法支持 | 无方法,仅存储值 | 提供数值转换、比较等工具方法(如 parseInt() 、compareTo() ) |
空值处理 | 不能为 null | 可为 null(需注意空指针) |
泛型支持 | 无法直接用于泛型 | 支持泛型(如 List<Integer> ) |
示例:
int num = Integer.parseInt("123"); // String → int
Integer value = Integer.valueOf("456");// String → Integer
int max = Integer.MAX_VALUE; // 获取 int 最大值
4. 自动装箱与拆箱
-
自动装箱(Autoboxing):Java 编译器自动将
int
转换为Integer
。 -
自动拆箱(Unboxing):自动将
Integer
转换为int
。
示例:
Integer a = 10; // 自动装箱:等价于 Integer.valueOf(10)
int b = a; // 自动拆箱:等价于 a.intValue()
性能注意: 自动装箱/拆箱会带来额外开销,高频操作时建议直接使用 int
。
5. 比较操作
比较方式 | int | Integer |
---|---|---|
== 比较 | 直接比较值是否相等 | 比较对象引用地址(除非值在缓存范围内) |
equals() | 不适用(基本类型无方法) | 比较值是否相等 |
示例:
int x1 = 1000;
int x2 = 1000;
System.out.println(x1 == x2); // true(值相等)
Integer y1 = 1000;
Integer y2 = 1000;
System.out.println(y1 == y2); // false(对象地址不同)
System.out.println(y1.equals(y2)); // true(值相等)
// 缓存范围测试(-128~127)
Integer z1 = 127;
Integer z2 = 127;
System.out.println(z1 == z2); // true(复用缓存对象)
6. 缓存机制(IntegerCache)
-
缓存范围:
Integer
类默认缓存-128
到127
之间的值。 -
目的:减少频繁创建小数值对象,优化内存和性能。
-
扩展缓存:可通过 JVM 参数
-XX:AutoBoxCacheMax=<size>
调整上限。
示例:
Integer a = 127; // 从缓存获取
Integer b = 127; // 复用缓存对象
System.out.println(a == b); // true
Integer c = 128; // 超出缓存范围,新建对象
Integer d = 128; // 新建另一个对象
System.out.println(c == d); // false
7. 使用场景
场景 | 推荐使用 | 原因 |
---|---|---|
高频计算 | int | 避免自动装箱开销,性能更优 |
集合存储 | Integer | 集合泛型不支持基本类型(如 List<int> 非法) |
数据库映射 | Integer | 数据库字段可能为 NULL,int 无法表示 |
API 设计 | Integer | 方法参数或返回值可能需区分“无值”(null) |
8. 常见问题与陷阱
(1) NullPointerException
Integer value = null;
int num = value; // 运行时抛出 NullPointerException(自动拆箱调用 intValue())
(2) 性能损耗
// 高频循环中自动装箱导致性能下降
long sum = 0;
for (Integer i = 0; i < 100000; i++) { // 每次循环触发装箱
sum += i;
}
(3) 比较错误
Integer a = 200;
Integer b = 200;
if (a == b) { // false,应使用 equals() 或 intValue() 比较
System.out.println("Equal");
}
总结
维度 | int | Integer |
---|---|---|
类型 | 基本数据类型 | 包装类(引用类型) |
内存 | 栈存储,高效 | 堆存储,有对象开销 |
空值 | 不支持 | 支持(需防空指针) |
方法 | 无 | 提供工具方法 |
适用场景 | 高频计算、性能敏感场景 | 集合、数据库映射、API 设计 |
选择建议:
-
优先使用
int
:在不需要对象特性(如 null 值、方法操作)时,提升性能。 -
必须使用
Integer
:在泛型集合、数据库映射或需要区分“无值”场景时。