欢迎光临
我们一直在努力

P01 · 空指针 NullPointerException:几乎每个 Java 程序员都踩过的坑

P01 · 空指针 NullPointerException:几乎每个 Java 程序员都踩过的坑

场景还原:你写了一个"按 id 查用户"的方法,数据库里刚好没有这条记录,方法返回了 null。调用方拿到这个 null 想都没想就 .name 取名字——“啪”,程序当场崩了,终端上留下一行刺眼的红字:NullPointerException。

这大概是 Java 世界里出现频率最高、也最让人又爱又恨的异常:它好懂,但架不住天天见。更气人的是,代码量大以后,你根本不知道是哪个"没判空"埋的雷。

一、问题现象

运行下面的代码,程序直接崩溃:

Exception in thread "main" java.lang.NullPointerException: Cannot read field "name" because "<local1>" is null
at NpeDemo.main(NpeDemo.java:19)

P01 运行报错截图

二、出错代码

public class NpeDemo {
static class User {
String name;
Address addr;
}
static class Address {
String city;
}

// 模拟"查不到用户"——数据库没这条记录/缓存为空时经常返回 null
static User queryUser(int id) {
return null;
}

public static void main(String[] args) {
User u = queryUser(1);
// 最常见的翻车点:拿到对象后没判 null 直接往下用
System.out.println("用户名: " + u.name); // ← 这里炸了
}
}

三、为什么会这样

一句话:null 上什么都没有,你却非要问它要东西。

u 是 null 时,u.name 等价于"对一个不存在的对象取属性",Java 只能抛 NullPointerException 告诉你"我做不到"。

注意 JDK 14 之后报错信息变得更贴心了,会直接告诉你是哪个引用是 null(because "<local1>" is null),定位比以前容易多了。

常见的"null 从哪来":

  • 数据库/接口查无记录,返回了 null;
  • Map.get(key) 键不存在,返回 null;
  • 链式调用的中间某一步返回了 null,比如 user.getAddress().getCity(),getAddress() 返回 null 就崩;
  • 第三方库/老代码的返回值没写"可能为 null"的注释。

四、怎么解决

第一层:源头堵——不确定有没有值的方法,要么返回 Optional,要么明确告诉调用方"可能为 null":

// 返回 Optional,调用方被迫考虑"没有值"的情况
static Optional<User> queryUser(int id) {
// 查不到就返回 Optional.empty()
return Optional.empty();
}

public static void main(String[] args) {
User u = queryUser(1).orElse(null);
if (u == null) { // 判空后再用
System.out.println("用户不存在,走兜底逻辑");
return;
}
System.out.println("用户名: " + u.name);
}

第二层:用的时候判——凡是"别人给你的对象",用之前先想一句"它可能是 null 吗":

String city = (u != null && u.addr != null) ? u.addr.city : "未知";

第三层:能自动挡就自动挡——Spring 等框架里可以加 @NotNull / @Nullable 注解,编译期插件能帮你提前发现一半问题。

五、防坑总结

  • 方法返回值可能是 null 时,要么文档注明,要么返回 Optional;
  • 调用外部方法/接口返回的对象前,先判空;
  • 链式调用(a.getB().getC())每层都可能空,拆开判或封装安全取值方法;
  • 集合用 getOrDefault、Map 查询用 containsKey 先判断;
  • 一个方法里 NPE 修完,顺手看看同类写法还有没有(复制粘贴是 NPE 的温床)。

下一篇:P02 · 序列化失败 NotSerializableException

赞(0)
未经允许不得转载:171主机测评 » P01 · 空指针 NullPointerException:几乎每个 Java 程序员都踩过的坑
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址