优雅判空

  • 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;  }

代码地址:这里

参考文献:

importnew

公众号:java 团长

我的主页