核心要点
- 自动装箱: 当你在
if条件中直接使用一个int类型的值(如10)时,Java 会自动将其转换为Integer对象。if (10 == ...)在编译时会变成if (Integer.valueOf(10) == ...)。 null检查:Integer是一个对象,它可以被赋值为null,如果对一个null的对象调用方法(如.intValue())或进行算术运算,会抛出NullPointerException,在if语句中必须考虑到null的情况。Integer缓存: Java 为了提高性能和节省内存,会缓存-128到127之间的Integer对象,这意味着Integer.valueOf(100)永远返回同一个对象实例,而Integer.valueOf(200)则可能返回新对象,这一点会影响 比较的结果。
基本类型 int 与 Integer 对象比较
这是最常见的场景,也是最容易出错的地方,关键在于理解 和 .equals() 的区别。

使用 进行比较
比较的是两个对象的内存地址(是否是同一个对象实例),而不是它们所代表的值。
情况 A:与基本类型 int 比较
当 if 的一边是 Integer 对象,另一边是基本类型 int 时,Java 会自动将 Integer 对象拆箱为 int 值,然后进行数值比较。
Integer num = 100; // 自动装箱,等同于 Integer.valueOf(100)
if (num == 100) {
System.out.println("执行了"); // 这行代码会执行
}
// 解释:num (Integer) 被拆箱为 int 值 100,然后与 100 进行比较,结果为 true。
情况 B:两个 Integer 对象比较()

这是最需要注意的陷阱,比较两个 Integer 对象是否相等,应该使用 .equals(),而不是 。
// 示例 1:在缓存范围内 [-128, 127]
Integer a = 100;
Integer b = 100;
if (a == b) {
System.out.println("a 和 b 是同一个对象"); // 这行代码会执行
}
// 解释:a 和 b 都是通过 Integer.valueOf(100) 创建的,JVM 从缓存中返回了同一个实例。
// 示例 2:超出缓存范围
Integer c = 200;
Integer d = 200;
if (c == d) {
System.out.println("c 和 d 是同一个对象"); // 这行代码不会执行
}
// 解释:c 和 d 都是通过 Integer.valueOf(200) 创建的,但 200 不在缓存范围内,JVM 创建了两个不同的新对象实例。
使用 .equals() 进行比较
.equals() 方法被 Integer 类重写,用于比较两个 Integer 对象所代表的数值是否相等,这是最安全、最推荐的比较方式。
Integer e = 100;
Integer f = 200;
if (e.equals(f)) {
System.out.println("e 和 f 的值相等"); // 不会执行
}
if (e.equals(100)) {
System.out.println("e 的值等于 100"); // 会执行
}
// 注意:当调用 e.equals(100) 时,基本类型 100 会被自动装箱为 Integer 对象,然后进行比较。
最佳实践:
当需要比较 Integer 对象的值时,始终使用 .equals()。
处理 null 值
Integer 作为对象,可以为 null,直接在 if 中使用 == null 是最直接的 null 检查方式。

检查是否为 null
Integer myNum = null;
// 正确的 null 检查
if (myNum == null) {
System.out.println("myNum 是 null"); // 这行代码会执行
}
避免 NullPointerException
在 if 条件中,Integer 变量可能为 null,要避免直接进行算术运算或比较,否则会抛出异常。
Integer nullableNum = null;
// 错误示范:会抛出 NullPointerException
// if (nullableNum > 5) { ... } // 编译错误,因为 > 不能用于 Integer 和 int
// if (nullableNum == 5) { ... } // 这行代码本身不会报错,因为会拆箱,但逻辑上可能不是你想要的
// 正确的做法是先检查 null
if (nullableNum != null && nullableNum > 5) {
System.out.println("nullableNum 大于 5");
} else {
System.out.println("nullableNum 是 null 或不大于 5"); // 这行代码会执行
}
短路评估:在 nullableNum != null && nullableNum > 5 中,nullableNum != null 为 false,整个表达式会立即确定为 false,而不会去执行后面的 nullableNum > 5,从而避免了 NullPointerException,这是非常安全的写法。
if-else if-else 链中的 Integer
在处理多个条件时,清晰地检查 null 和使用 .equals() 或数值比较非常重要。
Integer status = 200;
if (status == null) {
System.out.println("状态码为空");
} else if (status.equals(200)) {
System.out.println("操作成功"); // 这行代码会执行
} else if (status.equals(404)) {
System.out.println("资源未找到");
} else if (status > 500) {
System.out.println("服务器错误");
} else {
System.out.println("其他状态");
}
这个例子展示了如何安全地将 null 检查、.equals() 值比较和拆箱后的数值比较结合起来。
总结与最佳实践
| 场景 | 推荐写法 | 不推荐写法 | 原因 |
|---|---|---|---|
比较 Integer 与 int |
if (myInt == 10) |
if (myInt.equals(10)) |
在这里更简洁,Java 会自动拆箱,但 .equals() 也可以工作。 |
比较两个 Integer 对象 |
if (a.equals(b)) |
if (a == b) |
比较的是对象地址,受缓存影响,不可靠。.equals() 比较的是值,是正确的做法。 |
检查 Integer 是否为 null |
if (myInt == null) |
if (myInt.equals(null)) |
myInt.equals(null) myInt 是 null,会直接抛出 NullPointerException。 |
在条件中避免 NullPointerException |
if (myInt != null && myInt > 5) |
if (myInt > 5) |
先检查 null,利用短路效应防止异常。 |
if-else if 链 |
先 if (x == null),再用 else if (x.equals(...)) 或 else if (x > ...) |
混乱无序的检查 | 逻辑清晰,防止 NPE,代码易于维护。 |
记住黄金法则:
- 当
Integer可能为null时,永远先检查null。 - 当比较两个
Integer对象的值时,永远使用.equals()。 - 当
Integer与基本类型int比较时,使用 是安全且常见的。
