在写程序时,经常需要对创建的对象或属性进行null值判断,但是有时可能会疏忽没有对null进行判断,就会引发空指针问题,null值在程序设计语言中,是为了表示变量值的缺失;

java8中引入了Optional<T>,可以表示值的存在与不存在(null),对存在或不存在的变量值进行建模,并且可以避免空指针异常.

以下实例演示可以说明Optional<T>可以很好解决类型T为null时的问题。

package com.xiaomifeng1010.rbacboot.common.util;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;import java.util.Optional;
import java.util.function.Supplier;/*** @author xiaomifeng1010* @version 1.0* @date: 2020/3/21 16:18*/public class Java8Optional {/*** 在java8之前如果要保存Info对象,需要做多层非空检查,多层if嵌套* @param info*/
//    public void savaInfo(Info info){
//        if (info !=null){
//            if (info.getAddress() != null) {则保存info
//            }
//        }
//
//    }/*** 过多的退出语句* @param info*/
//    public void savaInfo2(Info info){
//        if (info==null){
//            return;
//        }
//        if (info.getAddress()==null){
//            return;
//        }
//    }//    Optional可以解决判断null问题/*** 创建Optional对象*/public void createOptional(){//    创建一个空白的OptionalOptional<Address> optionalAddress=Optional.empty();
//   依据一个非空值创建Optional(new Address()不能为null)Optional<Address> optionalAddress2=Optional.of(new Address());
//    可接受null值创建Optional(当new Address()为null时,调用empty()方法,创建一个空白Optional对象)Optional<Address> getOptionalAddress3= Optional.ofNullable(new Address());}/*** 使用map(同Stream API中的中间操作map)从optional对象中提取和转换值*/public void mapToOptional(){Optional<Address> addressOptional=Optional.ofNullable(new Address("南京路","20号"));
//        直接从Optional<Address>中获取Address类中street属性Optional<String> street=addressOptional.map(Address::getStreet);}public void flatMapToOptional(){Info info=new Info();Optional<Info> infoOptional=Optional.of(info);
//        再使用map就会报错,因为map转换输出的还是一个optional对象,会造成原本的optional里面存放optional对象
//        infoOptional.map(info -> info.getOptionalAddress());
//        可以使用flatMap方法从Info类中获取Optional<Address>,然后获取Address类型的street属性Optional<String> stringOptional=infoOptional.flatMap(Info::getOptionalAddress).map(Address::getStreet);System.out.println(stringOptional);}/*** 默认行为及解引用 optional对象*/@Testpublic void defaultValue(){Optional<Address> addressOptional= Optional.ofNullable(null);
//        获取街道名,如果无,则设置为"上海路"String street = addressOptional.map(Address::getStreet).orElse("上海路");System.out.println(street);}public static void main(String[] args) {Info info=new Info();info.setUsername("xiaomifeng1010");info.setPassword("123456");info.setAge(30);info.setOptionalAddress(Optional.of(new Address("广州路","12号")));boolean present=info.getOptionalAddress().filter(address -> address.
getDoor().contains("23"))
//      isPresent():如果存在值,则为true.不存在值,则为false.isPresent();System.out.println(present);//        address为null,过滤会报错,需要抛出异常,并处理info.setOptionalAddress(Optional.empty());Address address=null;try {address= info.getOptionalAddress().filter(address1 -> address1.getDoor().contains("34"))
.orElseThrow(new Supplier<Throwable>() {@Overridepublic Throwable get() {return new Exception("哎呀,出错了");}});} catch (Throwable throwable) {throwable.printStackTrace();}//          Info类中的年龄为30,不满足大于50,所以不会找到地址信息,输出“不存在”System.out.println(getSteet(Optional.of(info),50));}public static String getSteet(Optional<Info> info,int minAge){return info.filter(information -> information.getAge()>= minAge).
flatMap(Info::getOptionalAddress).map(Address::getStreet).orElse("不存在");}}/*** 自定义一个类Info*/
@Data
class Info{private String username;private String password;private Integer age;
//    private Address address;
/*** 为了解决空指针问题(即Address可能为null的情况),创建Optional对象,当Address未赋值初始化,* 会生成一个empty(空白)的Optional对象,而不会产生null(可以允许Address对象缺失)***/Optional<Address> optionalAddress;}/*** 住址对象*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class Address{/*** 街道*/private String street;/*** 门牌*/private String door;}

Optional<T>对应的常用方法:

方法 描述
empty 返回一个空的 Optional 实例
of 将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常
ofNullable 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象
map(Function<? super T, ? extends U> mapper)
如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
flatMap(Function<? super T, Optional<U>> mapper)
与map 类似,要求返回值必须是Optional
filter 如果值存在并且满足提供的断言, 就返回包含该值的 Optional 对象;否则返回一个空的 Optional 对象
get 如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常
public void ifPresent(Consumer<? super T> consumer)
如果值存在,就执行使用该值的方法调用,否则什么也不做
public boolean isPresent()
如果值存在就返回 true,否则返回 false
orElse 如果有值则将其返回,否则返回一个默认值(即orElse中设置的值
orElseGet(Supplier<? extends T> other)
如果有值则将其返回,否则返回一个由指定的 Supplier 接口生成的值
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
如果有值则将其返回,否则抛出一个由指定的 Supplier 接口生成的异常

java 8 Optional解决空指针异常问题相关推荐

  1. 使用Java 8 Optional避免空指针异常

    2019独角兽企业重金招聘Python工程师标准>>> Optional可以让你的代码具有可读性,且会避免出现空指针异常. 都说没有遇到过空指针异常的程序员不是Java程序员,nul ...

  2. 【Java基础】妙用Optional解决判断Null为空问题

    一.背景 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException. 回顾以前对null的处理方式: package com.biyu.study ...

  3. Java 8 - Optional全解

    文章目录 在Optional出现之前经常遇到的空指针异常 采用防御式减少NullPointerException (深度质疑) null-安全的第二种尝试(过多的退出语句) Optional的介绍以及 ...

  4. Java 8 Optional 类

    Java 8 Optional 类  Java 8 新特性 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. ...

  5. 【Java】Optional容器

    说明 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者 ...

  6. Java 8 Optional 类 学习

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/62216945 1. Optional类的简介 ...

  7. java.util.Optional

    API文档:https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html https://www.runoob.com/java/ ...

  8. Java 8 Optional:优雅地避免 NPE

    本篇文章将详细介绍 Optional 类,以及如何用它消除代码中的 null 检查.在开始之前首先来看下什么是 NPE,以及在 Java 8 之前是如何处理 NPE 问题的. 空指针异常(NullPo ...

  9. JAVA高级——Optional

    JAVA高级--Optional 二.为何要避免null指针 三.使用Optional优化null判断 3.1.1 使用Optional优化Car类 3.1.2 Optional的几种模式 3.1.3 ...

最新文章

  1. [原]对Linux环境下任务调度一点认识
  2. mysql安装连接测试c_C连接MySQL数据库开发之Windows环境搭建及测试_MySQL
  3. 用init-connect+binlog实现用户操作追踪【转】
  4. mysql数据字典生成,在线生成mysql数据字典
  5. Sublime Text 的快捷方式的用法
  6. 【OpenCV 例程200篇】07. 图像的创建(np.zeros)
  7. 6系A卡笔记本移动版:HD6470/6550/6630/6650/6730/6770M
  8. yzmcms图片自适应代码_基于segment.js制作的非常有创意的分段式SVG文字动画特效...
  9. HttpHelper使用记录
  10. jQuery LigerUI 初次发布一睹为快(提供Demo下载)
  11. docker network详解、教程
  12. 网传的南方某科技大学最新研究成果
  13. 提取小米手机系统完整包BOOT,及ROOT!
  14. 结合FME利用倾斜三维模型数据成果生成DSM等数据产品
  15. 商票逾期起诉怎么操作
  16. matlab将二值图像与原图重叠_MATLAB:增加噪声,同时多次叠加噪声图和原图以及求平均图像(imnoise,imadd函数)...
  17. 中国最早的计算机主机有多大,我国第一台计算机哪一年研制成功
  18. python文件怎么看代码表_TFRecord文件查看包含的所有Features代码
  19. android蓝牙开发简单获取android设备已经连接过(已适配)的蓝牙设备信息
  20. Navisworks Manage 2014简体中文版

热门文章

  1. 如何在MySQL中缩小/清除ibdata1文件
  2. python pip升级报错
  3. mybatis多对一,一对一,多对多resultMap映射,pojo映射,传参集合,封装的对象传参
  4. MDC记录activiti流程ID
  5. Proxy动态代理代码示例
  6. python的os为啥找不到文件_python使用os.listdir和os.walk获得文件的路径
  7. passwd: 鉴定令牌操作错误_user 及passwd 设置
  8. java split空值也保留_Java内存大家都知道,但你知道要怎么管理Java内存吗?
  9. 洛谷——P1422 小玉家的电费
  10. vue-cli 外部引入vue-router报错 Uncaught TypeError: Cannot redefine property: $router