一、背景
1.生产环境中Nullpointerexception是出现频率最高也是最低级的异常,防止 NPE,是程序员的基本修养。
2.学习常见防止NPE的手段,让自己的代码无NPE。
二、NPE可能产生的场景
1.普通obj.getA() 对象调用属性,易产生 NPE。
2.级联调用 obj.getA().getB().getC(); 一连串调用,易产生 NPE。
3.集合嵌套循环调用 for{ for {for}}; 易产生 NPE。
4.很多场景是,你以为这个对象不会空的,但偏偏有个场景过来就是空的,然后NPE悲剧发生了。
三、第一种例子
1.字符变量为空情况
apache工具包,用起来很好,字符常见操作选择StringUtils没错。
1.1.依赖导入
commons-lang
commons-lang
2.6
1.2.测试
public class TestNPE {
public static void main(String[] args) {
String name=null;
if (StringUtils.isEmpty(name)){
System.out.println("测试 StringUtils null");
}
}
}
1.3.结果
测试 StringUtils null
2.集合为空情况
spring中自带的工具很多,大家可以没事的时候去总结下
2.1.测试类
public class TestNPE {
public static void main(String[] args) {
ArrayList
2.2.结果
测试 CollectionUtils null
3.对象为空情况
这个是java jdk自带的
3.1.实体类
public class TestDemoDTO{
private String name;
private Map citys;
private Date gmtStart;
private Boolean flag;
private Integer age;
private List types;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map getCitys() {
return citys;
}
public void setCitys(Map citys) {
this.citys = citys;
}
public Date getGmtStart() {
return gmtStart;
}
public void setGmtStart(Date gmtStart) {
this.gmtStart = gmtStart;
}
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
this.flag = flag;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public List getTypes() {
return types;
}
public void setTypes(List types) {
this.types = types;
}
@Override
public String toString() {
return "TestDemoDTO{" +
"name='" + name + '\'' +
", citys=" + citys +
", gmtStart=" + gmtStart +
", flag=" + flag +
", age=" + age +
", types=" + types +
'}';
}
}
3.2.测试类
public class TestNPE {
public static void main(String[] args) {
TestDemoDTO testDemoDTO = new TestDemoDTO();
testDemoDTO=null;
if (java.util.Objects.isNull(testDemoDTO)){
System.out.println("测试 Object null");
}
}
}
四、结果
测试 Object null
注意:因为你new对象的时候,对象的引用都会有一个地址值,所以先把引用类型变量变为null,然后才可以测试。
五、第二种例子
google guava对象、集合、字符为空情况,我们的谷歌,这个防空工具很不错,什么对象都防的住。
1.对象为空情况
用的google的防止null工具。
2.测试类
public class TestNPE {
public static void main(String[] args) {
TestDemoDTO testDemoDTO = new TestDemoDTO();
testDemoDTO=null;
if (com.google.common.base.Objects.equal(testDemoDTO,null)){
System.out.println("测试 Object null");
}
}
}
3.结果
测试 Object null
2.Optional防空
2.1.java JDK8新特性 使用Optional避免null导致的NullPointerException, ofNullable允许有null值
2.1.1.Optional (Optional是个容器可以装集合、对象、字符变量等)
2.1.2.isPresent():判断值是否存在 (先判断在 get())
2.1.3.optional.get() 获取对象值
2.2.测试类
public class TestNPE {
public static void main(String[] args) {
List list = Lists.newArrayList();
Optional> optional = Optional.ofNullable(list);
if (optional.isPresent()){
System.out.println("Optional.ofNullable有值"+optional.get());
}else{
System.out.println("Optional null");
}
}
}
2.3.结果
Optional.ofNullable有值[]
注意:ofNullable允许有null值,也是可以避免空指针的。
3.嫌弃isPresent()判断太麻烦,下面这个更简洁优雅,ofNullable的值为null时,就赋值个空集合对象,然后就可以安全的遍历了。
3.1.测试类
public class TestNPE {
public static void main(String[] args) {
List list = Lists.newArrayList();
list.add("111");
Optional> optional = Optional.ofNullable(list);
Optional.ofNullable(list).orElse(Collections.emptyList()).forEach(g -> System.out.println(g));
}
}
3.2.结果
111
注意默认空值,建议用下面这两个,一个空集合、一个空字符。
new 集合会消耗资源。
3.3.总结:
1.使用 Optional 时不要直接调用 Optional.get() 方法
2.最好的理解 Optional 的莫过于看它的源代码,功能非常多,我也一直在学习中。
3.google guava工具里面函数式编程非常到位
六、结束
Always keep the faith!!!