首先要知道什么情况下会发生空指针
当一个变量的值为null时,在java里面表示一个不存在的空对象,没有实际的内容,没有给它分配内存,null也是对象成员变量的默认值。
所以,一个对象如果没有进行初始化操作,这时候,如果你调用这个对象的方法或者变量,就会出现空指针异常。
例如:
Object object = null;
String str = object.toString();
NullPointerException属于运行时异常RuntimeException的子类,他不是捕获型的,只有在程序运行时才能报出来,而且会造成程序中断。
如何避免空指针
字符串比较,常量放在前面
if(status.equals(SUCCESS)){
}
上面这种情况下 status可能为null造成空指针异常,应该把常量放在前面,就能避免空指针异常。如下:
if(SUCCESS.equals(status)){
}
初始化默认值
在对象初始化的时候给它一个默认值或者默认构造实现 如:
Uses uses = new Uses;
String name = StringUtils.EMPTY;
返回空集合
在返回一个集合的话,默认会是NULL,统一规范返回一个空集合。如下:
public List getUsesList(){
List list = usesMapper.getUsesList();
return list == null ? new ArrayList() : List;
}
断言
断言是用来检查程序的安全性的,在使用之前进行检查条件,如果不符合条件就报异常,符合就继续程序。
Java中自带的断言关键字,assert 如:
assert name == null : "名称不能为空";
输出:Exception in thread “main” java.lang.AssertionError: 名称不正确
不过默认是不启动断言检查的,需要带上JVM参数: -enableassertions才能生效。
Java中这个用的很少,建议使用Spring中的。
Assert.notNull(name,"名称不能为空");
Optional
Optional是JDK1.8新增的新特性,再也不用 != NULL来判断了 。这个在一个对象里面的多个子对象连续判断的时候非常有用。
//以前的判空
String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String isocode = country.getIsocode();
if (isocode != null) {
isocode = isocode.toUpperCase();
}
}
}
}
//Optional判空
String result = Optional.ofNullable(user).flatMap(User::getAddress).flatMap(Address::getCountry).map(Country::getIsocode).orElse("default");