title: Java技巧系列( 一 )优雅判空
date: 2019-01-08 12:00:00 +0800
update: 2019-01-08 12:00:00 +0800
author: me
cover: https://ws1.sinaimg.cn/large/006jIRTegy1fyz2n5rl6jj31hc0u0ar5.jpg
preview: 作为搬砖党的一族们,对判空一定再熟悉不过了,不要说你很少进行判空
tags:
- Java技巧系列
文章目录
Java技巧系列( 一 )优雅判空
为什么要判空
null是Java中一个很重要的概念。null设计初衷是为了表示一些缺失的东西,例如缺失的用户、资源或其他东西。
Tony Hoare 自己说过:
我将1965年发明的 null 称作我百万美元的错误。那个时候,我正在设计第一个面向对象语言(ALGOLW)中的引用的综合类型系统。我的目标是确保所有引用的使用都绝对安全,由编译器自动执行检查确保安全。但我无法抵挡放入空引用的诱惑,仅仅因为这个很容易实现。这个决定导致了不计其数的错误、漏洞和系统崩溃,在其后的四十年可能已经造成了百万美元的损失。
什么需要判空
有两种情况会出现判空语句:
- null返回值按找约定是正常的返回值
- null返回值不是正常的返回值
第二种情况很简单。可以使用assert来判断或者是允许程序报错(即抛NullPointerException)。断言是一个被充分利用的Java特性,在1.4版本中加入了这个特性。
第一种情况就要难解释一点了。如果你对你调用的代码没有控制权的话,你就惨了。如果null返回值是正常的话,那你就必须去检查它了。
如果可以控制你调用代码(当然常常还是有控制权的),那就是另一回事儿了。还是尽量的不去使用null返回值。对于返回集合的方法很简单,只需要返回空的集合就可以了,而不是null。
如何优雅判空
NULL Object 设计模式
Nullable是空对象的相关操作接口,用于确定对象是否为空,因为在空对象模式中,对象为空会被包装成一个Object,成为Null Object,该对象会对原有对象的所有方法进行空实现…
Optional
1、Optional.ofNullable(test),如果test为空,则返回一个单例空Optional对象,如果非空则返回一个Optional包装对象,Optional将test包装;
2、flatMap(Test::getTest3)判断test是否为空,如果为空,继续返回第一步中的单例Optional对象,否则调用Test的getTest3方法;
3、flatMap(Test3::getTest2)同上调用Test3的getTest2方法;
4、map(Test2::getInfo)同flatMap类似,但是flatMap要求Test3::getTest2返回值为Optional类型,而map不需要,flatMap不会多层包装,map返回会再次包装Optional;
5、orElse("");获得map中的value,不为空则直接返回value,为空则返回传入的参数作为默认值。
简单的demo
Main.java
public class MainTest {
@Test
public void testNPE(){
Father father = new Father();
father.getChildrenOne().getAge();
}
@Test
public void testOptional(){
Father father=null;
//简介版
System.out.println(Optional.ofNullable(father).map(Father::getChildrenOne).orElse(null));
//分解版
Optional<Father> father1 = Optional.ofNullable(father);
System.out.println(father1);
Optional<ChildrenOne> childrenOne = father1.map(Father::getChildrenOne);
System.out.println(childrenOne);
ChildrenOne x = childrenOne.orElse(new ChildrenOne());
System.out.println(x);
//判断option包装的类是否为空
Optional<Object> empty = Optional.empty();
}
}
Father.java
@Data
public class Father {
private int sonNum;
/**
* 如果sonNum > 1 则返回示例,否则 返回空;
**/
ChildrenOne getChildrenOne(){
return sonNum > 1 ? new ChildrenOne() : null;
}
/**
* 若果sonNum >2 则返回示例, 否则 返回空
**/
ChildrenTwo getChildrenTwo(){
return sonNum>2 ? new ChildrenTwo() : null;
}
}
ChildrenOne.java
@Data
public class ChildrenOne {
private Integer age=100;
public ChildrenOne(Integer age) {
this.age = age;
}
public ChildrenOne() {
}
}
ChildrenTwo.java
@Data
public class ChildrenTwo {
private Integer age=100;
}
代码地址:这里
参考文献:
公众号:java 团长