优雅判空
- 2019 年 10 月 5 日
- 笔记
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37933685/article/details/86094814
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 团长