基础类型(int、boolean等)不会引发空指针异常,因其有默认值且无null;真正风险在于包装类(integer、boolean等)在自动拆箱或调用方法时遇null导致npe,需通过判空、optional、工具类或规范设计规避。

基础类型本身不会引起空指针异常(NullPointerException),因为它们没有引用,也没有 null 值——int、double、boolean、char、long、short、byte、float 这些基本数据类型在声明时就有明确的默认值(如 int 默认为 0,boolean 默认为 false)。真正出问题的,是它们的包装类(Integer、Double、Boolean、Character 等)。
包装类自动拆箱导致 NPE
当包装类变量为 null,又参与算术运算、比较或赋值给基本类型时,JVM 会尝试自动拆箱,此时就会抛出 NullPointerException。
-
错误写法:
Integer num = null; int value = num + 10;→ 拆箱失败,NPE -
错误写法:
Boolean flag = null; if (flag) { ... }→ 拆箱为 boolean 失败,NPE -
错误写法:
Double price = null; System.out.println(price.doubleValue());→ 显式调用方法,NPE
安全处理包装类空值的常用方式
核心原则:不依赖自动拆箱,先确认非 null 再使用。
- 显式判空后转换:
int value = (num != null) ? num : 0; - 用 Objects.requireNonNull() 提前拦截:
int value = Objects.requireNonNull(num, "num must not be null");(注意:这仍会抛异常,但更明确) - 用 Optional 封装(推荐用于返回值或中间计算):
Optional<integer> opt = Optional.ofNullable(num); int value = opt.orElse(0);</integer> - 使用 Guava 或 Apache Commons 工具类:
Ints.constrainToRange(num, 0, 100)或ObjectUtils.defaultIfNull(num, 0)
方法参数和返回值设计建议
从源头减少隐患比事后补救更有效。
- 方法参数尽量用基本类型(如 int)而非包装类(Integer),除非需要表达“缺失”语义
- 如果必须用包装类作参数,用
@NonNull(Lombok)或Objects.requireNonNull()在入口校验 - 避免方法返回 null 的包装类;优先返回默认值(如 0)、Optional,或抛出业务异常
- 数据库映射或 JSON 解析场景中,配置框架默认填充基础类型(如 MyBatis-Plus 的
@TableField(fill = FieldFill.INSERT)或 Jackson 的@JsonSetter(nulls = Nulls.SKIP))
容易被忽略的边界情况
有些看似“安全”的操作其实暗藏风险:
-
Integer a = null, b = 1; Integer c = a + b;→ 依然触发自动拆箱,NPE -
if (status == Status.ACTIVE)(其中 status 是枚举包装类)→ 若 status 为 null,直接 NPE - 流式操作:
list.stream().map(Item::getPrice).filter(p -> p > 100).count()→ 若 getPrice() 返回 null,filter 里比较会 NPE










