自动装箱陷阱
空值拆箱与 == 陷阱
自动装箱陷阱 是 CoddyKit 上的免费 Java Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
便利功能也有陷阱
自动装箱可以让代码更简洁,但它隐藏的转换可能导致令人意外的错误。最大的两个陷阱是空值拆箱和使用 == 进行身份比较。
本课将介绍如何避免这两个问题。
空值拆箱陷阱
如果包装类型保存的是 null,而您将其拆箱为基本类型,Java 就会抛出 NullPointerException。
这个问题很容易被忽略,因为代码看起来只是一次简单的赋值。
public class Main {
public static void main(String[] args) {
Integer maybe = null;
try {
int value = maybe;
System.out.println(value);
} catch (NullPointerException e) {
System.out.println("Cannot unbox null!");
}
}
}算术运算中的空值
这个陷阱也会出现在表达式中。将 null 包装类型参与相加时,Java 会先对其拆箱;因此在数学运算开始前就会抛出异常。
public class Main {
public static void main(String[] args) {
Integer count = null;
try {
int total = count + 5;
System.out.println(total);
} catch (NullPointerException e) {
System.out.println("Null in arithmetic!");
}
}
}防止空值问题
在对包装类型进行拆箱之前,请始终检查它是否为 null,或者为它提供默认值。
public class Main {
public static void main(String[] args) {
Integer maybe = null;
int safe = (maybe != null) ? maybe : 0;
System.out.println(safe);
}
}== 缓存陷阱
Integer.valueOf 会缓存 -128 到 127 之间的值。因此,这个范围内的两个装箱值可能共享同一个对象,而 == 会返回真。
public class Main {
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
}
}超出缓存范围
超出缓存范围后,每次装箱都会创建不同的对象。此时,== 比较的是引用,即使数字相等,也会返回假。
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
}
}始终使用 equals
由于对包装类型使用 == 比较的是对象身份,您必须使用 .equals() 比较实际数值。
public class Main {
public static void main(String[] args) {
Integer a = 200;
Integer b = 200;
System.out.println(a.equals(b));
}
}将 == 与基本类型混用
如果 == 的一侧是基本类型,Java 会拆箱包装类型,因此比较的是值。这种方式可靠,但包装类型为空时仍可能抛出异常。
public class Main {
public static void main(String[] args) {
Integer a = 200;
int b = 200;
System.out.println(a == b);
}
}循环中的隐式装箱
将循环累加器声明为包装类型,会在每次迭代中创建一个新对象。下面,如果使用 Long 而不是 long,就会反复装箱。请优先使用基本类型。
public class Main {
public static void main(String[] args) {
long sum = 0;
for (int i = 0; i < 1000; i++) {
sum += i;
}
System.out.println(sum);
}
}Map.get 返回空值
一个常见的实际问题是:对于缺失的键,Map.get 会返回 null。将该结果拆箱为 int 会抛出异常。请改用 getOrDefault。
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
int score = scores.getOrDefault("missing", 0);
System.out.println(score);
}
}确保安全
两个习惯可以避免大多数自动装箱问题:永远不要拆箱可能为 null 的值,并且始终使用 .equals() 而不是 == 比较包装类型的值。
快速检查
测试您对自动装箱陷阱的认识。
回顾
您已经了解自动装箱的主要陷阱:
- 拆箱值为
null的包装类型会抛出NullPointerException - 使用空值检查或默认值进行防护
- 对包装类型使用
==比较的是引用,缓存范围为 -128 到 127 - 比较值时始终使用
.equals() - 使用
getOrDefault,避免映射查找返回空值
常见问题解答
「自动装箱陷阱」课时是免费的吗?
是的 — 「自动装箱陷阱」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「自动装箱陷阱」这节课中我会学到什么?
空值拆箱与 == 陷阱 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「自动装箱陷阱」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。