1、什么是Optional
Java 8引入Optional类来防止空指针异常,Optional类实际上是个容器:它可以保存类型T的值,或者保存null。使用Optional类我们就不用显式进行空指针检查了。
2、为什么要用Optional
用Optional避免null带来的种种问题:
- null是错误之源
NullPointerException是目前Java程序开发中最典型的异常。
- null使你的代码膨胀
它让你的代码充斥着深度嵌套的null检查,代码的可读性糟糕透顶。
- 自身是毫无意义的
null自身没有任何的语义,尤其是,它代表的是在静态类型语言中以一种错误的方式对缺失变量值的建模。
- 破坏了Java的哲学
Java一直试图避免让程序员意识到指针的存在,唯一的例外是:null指针。
- 在Java的类型系统上开了个口子
null并不属于任何类型,这意味着它可以被赋值给任意引用类型的变量。这会导致问题,原因是当这个变量被传递到系统中的另一个部分后,你将无法获知这个null变量最初的赋值到底是什么类型。
3、如何使用Optional
3.1、创建Optional对象
- 创建一个空的Optional
Optional optUserBean = Optional.empty();
- 依据一个非空值创建Optional
Optional optUserBean = Optional.of(userBean);
如果userBean是一个null,这段代码会立即抛出一个NullPointerException,而不是等到你试图访问userBean的属性值时才返回一个错误。
- 可接受null的Optional
Optional optUserBean = Optional.ofNullable(userBean);
如果userBean是null,那么得到的Optional对象就是个空对象。
3.2、isPresent
如果值存在返回true,否则返回false。
if (optUserBean.isPresent()) { System.out.println(optUserBean.get()); }
3.3、get
如果该值存在,将该值用Optional封装返回,否则抛出一个NoSuchElementException异常。
3.4、ifPresent
如果值存在,就执行使用该值的consumer方法调用,否则什么也不做。
optUserBean.ifPresent(p->{System.out.println(p.getName());});
3.5、orElse
如果有值则将其返回,否则返回一个默认值。
UserBean userBean = optUserBean.orElse(null);
3.6、orElseGet
如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值。
3.7、orElseThrow
如果有值则将其返回,否则抛出一个由指定的Supplier 接口生成的异常。
3.8、map
如果值存在,就对该值执行提供的mapping 函数调用。
String name = optUserBean.map(p->p.getName()).orElse(null);
3.9、flatMap
如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象。
String name = optUserBean.flatMap(p -> Optional.of(p.getName())).orElse(null);
3.10、filter
如果值存在并且满足提供的条件,就返回包含该值的Optional对象;否则返回一个空的Optional对象。
UserBean myUserBean = optUserBean.filter(p->p.getName().equals("Stanley")).orElse(null);
4、最佳实践
实际工作中,我们通常会有如下代码,UserBean中获取LongId这个字符串并且转成int:
- Java7写法
private static int StringToIntWithJava7(UserBean userBean) { int value = -1; if (null != userBean) { String loginId = userBean.getLoginId(); if (null != loginId) value = Integer.parseInt(loginId); } return value; }
- Java8写法:
private static int StringToIntWithJava8(UserBean userBean) { return Optional.ofNullable(userBean).map(UserBean::getLoginId).map(Integer::parseInt).orElse(-1);}
无疑Java8中的Optional能让你从繁琐丑陋的判空代码中解放出来,优雅的解决了NullPointException的问题。
专业从事软件研发工作多年,在软件设计、开发、测试、研发管理等领域里经验丰富,感兴趣的朋友可以关注我的头条号,相信一定会有所收获。
如果有软件研发方面的问题,可以咨询我。
谢谢!