首先要明确,NullPointerException
是一种代码逻辑错误,需要将try catch撤掉
理论上,可以通过良好编程习惯避免这种错误,比如:
成员变量在定义时初始化:
public class Person {
private String name = "";
}
使用空字符串""
而不是默认的null,包括编写业务逻辑时,返回空字符串,空数组而非null.
然后又了解了optional.isPresent(),从 Java 8 引入的一个 Optional 类,isPresent();可以判断查询的类对象是否存在,方法如下:
Optional optional = courseDao.findById(courseId);
if(optional.isPresent()){
optional.get();
…
}
isPresent()一般与.get()方法合用,当optional中存在course时,optional.isPresent()值为true,通过get()方法返回对象。
若不能解决,那么就想办法定位NullPointerException。
从Java 14开始,JVM可以自己在控制台告诉我们是哪一部分出现了问题
public class Main {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.address.city.toLowerCase());
}
}
class Person {
String[] name = new String[2];
Address address = new Address();
}
class Address {
String city;
String street;
String zipcode;
}
可以在NullPointerException
的详细信息中看到类似... because "<local1>.address.city" is null
,意思是city
字段为null
,这样我们就能快速定位问题所在。
这种增强的NullPointerException
详细信息是Java 14新增的功能,但默认是关闭的,我们可以给JVM添加一个-XX:+ShowCodeDetailsInExceptionMessages
参数启用它:
java -XX:+ShowCodeDetailsInExceptionMessages Main.java
了解了以上知识后,就可以解决大部分问题了,然后我尝试定位,发现原来是我注入service时忘记加@Autowire注解了,然后就这样解决了这个看似困难的报错。