0Pricing
Java Academy · 课时

自动装箱陷阱

空值拆箱与 == 陷阱

自动装箱陷阱 是 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 基本类型与包装类型
  2. 自动装箱与拆箱
  3. 解析与 Valueof
  4. 自动装箱陷阱
← 返回 Java Academy