写Java的人,谁没被NullPointerException坑过?编译器不报错,运行时直接崩,排查起来还特别恶心。2026年了,Java 21都出了好几个更新版本,空指针异常依然稳居线上Bug榜前三。今天把最容易踩坑的5个场景和对应的解法全拆开,以后写代码之前先过一遍,能少熬不少夜。
NullPointerException是运行时异常,不是编译时异常。什么意思?你写了一段调用null对象方法的代码,javac编译的时候压根不管,一路绿灯通过。等程序跑起来,到了那一行,JVM一看——对象是null,没法调方法,直接抛异常。
这就是它最恶心的地方:编译期发现不了,测试环境可能也没触发,偏偏上线之后炸了。
根据2025年某云服务商的线上故障统计,Java应用的崩溃原因里,NullPointerException占了23.7%,排第一。比数组越界、类型转换异常加起来都多。所以这东西不是小问题,是真会影响生产环境的。
这个场景我自己踩过不下10次。
javaConnection con = DriverManager.getConnection(url, root, password);
con.close();
看着没毛病对吧?但如果url里端口号错了、root用户名不对、password密码有问题,getConnection返回的就是null。con是null,你调con.close(),NullPointerException直接飞出来。
更惨的是什么?如果你把close()写在finally块里,异常还会把原来的错误信息盖掉,日志里只看到NPE,根本不知道是数据库连接失败导致的。
解法就一行:
javaif (con != null) {
con.close();
}
或者用Java 7之后的try-with-resources,自动关闭,连判断都省了:
javatry (Connection con = DriverManager.getConnection(url, root, password)) {
// 你的业务逻辑
}
2026年的Java 21里,虚拟线程加了新的资源管理特性,但数据库连接这块,try-with-resources依然是最稳妥的写法,别图省事。
javaString str = null;
int len = str.length(); // 炸了
这个太常见了。很多人从接口拿回来一个String,没判空直接用,十有八九出事。
关于String还有个坑得说一下。String str = "abcd"和String str = new String("abcd"),效果一样吗?表面看一样,底层不一样。前者走字符串常量池,后者在堆内存里新开一块空间。但不管哪种,str如果是null,调任何方法都会抛NPE。
还有一个细节:类的成员变量,引用类型默认值就是null。你写private static String str;,不赋值的话str就是null,不是空字符串""。这个坑很多初学者不知道,调str.length()的时候莫名其妙就崩了。
javaint[] array = null;
int len = array.length; // NPE
数组和对象一样,没初始化就是null。有人习惯写if (array.length > 0)来判断数组有没有元素,但如果array本身是null,这行代码在判断之前就已经炸了。
正确写法:
javaif (array != null && array.length > 0) {
// 你的逻辑
}
注意短路运算符&&的顺序,null判断必须放前面。如果反过来写array.length > 0 && array != null,一样会报错,因为&&是从左往右算的,左边先执行。
这个场景看着简单,实际是重灾区。
javaString str = null;
str.equals("faker"); // NPE
str是null,你让null去调equals方法,当然炸。
换个写法:
java"faker".equals(str);
把常量放前面,str放后面。就算str是null,equals方法是在"faker"这个常量对象上执行的,不会报错,直接返回false。
有人说这不就是个习惯问题吗?对,就是习惯问题。但就是这个习惯,能帮你避开至少30%的NPE。2026年了,IDE虽然能给你警告,但告警不等于不会上线。代码 review的时候多看一眼equals的调用顺序,花不了5秒钟。
javaString str = new Scanner(System.in).nextLine();
int len = str.length();
Scanner的nextLine()在某些边界条件下会返回null,比如输入流已经关闭了。如果你没判空直接用,NPE就来了。
类似的还有Map.get(),key不存在的时候返回null,不是抛异常。很多人以为get不到就会报错,结果拿到null继续往下走,三五行代码之后才炸,排查的时候根本不知道是哪一步出的问题。
解法还是那句话:拿到可能为null的引用,第一件事就是判空。
javaString str = new Scanner(System.in).nextLine();
if (str != null && !str.isEmpty()) {
int len = str.length();
}
多写一个if,少排查半小时。

有,但还不完美。
Java 14引入了NullPointerException的详细信息,报错的时候会告诉你到底是哪个变量为null、在哪一行出的问题。Java 21的虚拟线程里也加强了null检查的提示。
另外,Optional类从Java 8就有了,2026年用得好的团队已经把它当标配了。返回值可能为null的方法,直接返回Optional,调用方必须解包,想忽略都不行:
javaOptional<String> getName() {
return Optional.ofNullable(name);
}
比满屏的if (xx != null)干净多了。但说实话,国内很多项目还在用Java 8甚至Java 7,Optional推不动。那就老老实实写判空,别嫌烦。
空指针异常这东西,说到底就是一个字:懒。懒得判空,懒得检查,懒得写防御性代码。把上面5个场景记下来,写代码的时候对照着查一遍,线上NPE能少一半。
武汉格发信息技术有限公司,格发许可优化管理系统可以帮你评估贵公司软件许可的真实需求,再低成本合规性管理软件许可,帮助贵司提高软件投资回报率,为软件采购、使用提供科学决策依据。支持的软件有: CAD,CAE,PDM,PLM,Catia,Ugnx, AutoCAD, Pro/E, Solidworks 等。