在程序运行时,空指针异常应该是最常见的异常之一,因此JDK8提供了Optional来避免空指针异常。

首先说明JDK8新增的Optional及相关方法的使用

Optional的常用操作:
  Optional.of(T value) 创建一个Optional实例
  Optional.empty() 创建一个Optional空实例
  Optional.ofNullable(T value) 不为null,创建一个Optional实例,否则创建一个Optional空实例
  isPresent 判断是否包含值
  orElse(T t) 如果调用的对象包含值,则返回值,否则返回t
  orElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
  map(Function f) 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
  flatMap(Function f) 与mapleis,要求返回值必须是Optional 接下来逐个演示使用方式
1、Optional.of(T value)    创建一个Optional实例,但是只能创建非空数据
        Optional<Student> optional = Optional.of(new Student("lcl",16));
log.info("optional.get()======================{}",optional.get());
//可以快速定位NullPointExecption位置
Optional<Student> optional1 = Optional.of(null);//320行
log.info("optional1.get()======================{}",optional1.get());

运行结果

可以看到,在第一次创建时,new了一个对象作为入参,成功创建了Optional对象,但是第二次创建时,由于入参是空值,因此创建失败,报空指针异常,且报错行数为320行(代码标红处)。

2、Optional.empty()     创建一个Optional空实例
        //Optional.empty()     创建一个Optional空实例
Optional<Student> optional2 = Optional.empty(); //324行
log.info("optional2.get()======================{}",optional2.get());//325行

运行结果:

可以看到在在324行创建了一个空的Optional,但是由于是空的,因此在325行使用get方法时,报了没有对象的异常信息

3、Optional.ofNullable(T value)  不为null,创建一个Optional实例,否则创建一个Optional空实例
        //Optional.ofNullable(T value)  不为null,创建一个Optional实例,否则创建一个Optional空实例
Optional<Student> optional2 = Optional.ofNullable(new Student("lcl",16));//328行
log.info("optional2.get()======================{}",optional2.get());
Optional<Student> optional3 = Optional.ofNullable(null);
log.info("optional3.get()======================{}",optional3.get());

测试结果:

测试结果中,创建optional2时,由于入参是新创建的对象,因此optional2不为空,使用get方法时,正常获取到数据,但是optional3创建时的入参是空,因此创建了一个空的Optional对象,因此使用get方法时,出现异常。

4、isPresent  判断是否包含值(为了防止前几步的异常信息,jdk8提供了判断optional是否为空的方法isPresent)
        Optional<Student> optional = Optional.of(new Student("lcl",16));
Optional<Student> optional2 = Optional.ofNullable(new Student("lcl",16));
log.info("optional.isPresent()======================{}",optional.isPresent());
log.info("optional1.isPresent()======================{}",optional2.isPresent());

测试结果:

2020-06-01 14:58:40.381  INFO 18628 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : optional.isPresent()======================true
2020-06-01 14:58:40.383 INFO 18628 --- [ main] com.example.jdk8demo.Jdk8StreamDemoTest : optional1.isPresent()======================true
5、orElse(T t)   如果调用的对象包含值,则返回值,否则返回t
        //ofElse(T t)   如果调用的对象包含值,则返回值,否则返回t
Optional<Student> optional = Optional.ofNullable(new Student("mm",25));
Optional<Student> optional2 = Optional.ofNullable(null); Student student = optional.orElse(new Student("lcl",18));
log.info("orElse======================{}",student);
student = optional2.orElse(new Student("lcl",18));
log.info("orElse======================{}",student);

测试结果:

2020-06-01 15:00:42.765  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElse======================{"age":25,"name":"mm"}
2020-06-01 15:00:42.920 INFO 18864 --- [ main] com.example.jdk8demo.Jdk8StreamDemoTest : orElse======================{"age":18,"name":"lcl"}
6、orElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
        //ofElseGet(Supplier s) 如果调用对象包含值,则返回值,否则返回s获取的值
Optional<Student> optional2 = Optional.empty();
Student student1 = optional2.orElseGet(()->new Student("mm",16));
log.info("orElseGet======================{}",student1);
optional2 = Optional.of(new Student("kk",10));
Student student2 = optional2.orElseGet(()->new Student("mm",16));
log.info("orElseGet======================{}",student2);

测试结果:

2020-06-01 15:00:42.921  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : orElseGet======================{"age":16,"name":"mm"}
2020-06-01 15:00:42.922 INFO 18864 --- [ main] com.example.jdk8demo.Jdk8StreamDemoTest : orElseGet======================{"age":10,"name":"kk"}
备注:这里有个点需要说明一下,就是如果T是一个调用,例如orElse(aaa.getStudent()),那么最好不要使用orElse,要使用orElseGet,因为orElse无论调用对象是否有值,

aaa.getStudent()都会被执行,如果是调用第三方接口,那就每次都会多一次请求,而orEleseGet就没有问题,如果调用对象为不为空,则不会走内置接口。
7、map(Function f)  如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
        Optional<Student> optional2 = Optional.of(new Student("kk",10));
Optional<String> name = optional2.map((x)->x.getName());
log.info("map======================{}",name);

测试结果:

2020-06-01 15:00:42.923  INFO 18864 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : map======================Optional[kk]
8、flatMap(Function f)   与mapleis,要求返回值必须是Optional,与map的差异:map返回值为Optional,flatMap返回值为Optional<Optional>
        optional2 = Optional.of(new Student("kk",10));
Optional<String> name1 = optional2.flatMap((x)->Optional.of(x.getName()));
log.info("flatMap======================{}",name1);

 测试结果:

2020-06-01 15:05:41.552  INFO 14604 --- [           main] com.example.jdk8demo.Jdk8StreamDemoTest  : flatMap======================kk

JDK8--08:Optional的更多相关文章

  1. Java8新特性之五:Optional

    NullPointerException相信每个JAVA程序员都不陌生,是JAVA应用程序中最常见的异常.之前,Google Guava项目曾提出用Optional类来包装对象从而解决NullPoin ...

  2. swift:Optional Type 、Swift和Objective-C混编的讲解

    ❤️❤️❤️swift中的Optional Type的?和!含义:其实就是一个装包和拆包的过程 optional的含义: Optional事实上是一个枚举类型,Optional包含None和Some两 ...

  3. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

  4. Spring Boot → 08:嵌入式Servlet容器自定义

    Spring Boot → 08:嵌入式Servlet容器自定义

  5. Java 8新特性(三):Optional类

    在上一篇介绍Stream流式数据处理的文章中提到了Optional类,这是Java 8新增的一个类,用以解决程序中常见的NullPointerException异常问题.本篇文章将详细介绍Option ...

  6. Guava学习笔记(1):Optional优雅的使用null

    转自:http://www.cnblogs.com/peida/archive/2013/06/14/Guava_Optional.html 参考:[Google Guava] 1.1-使用和避免nu ...

  7. 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇08:弹幕系统》本系列完结

    8.弹幕系统 弹幕系统概述: 弹幕系统的设计体现了射击游戏的基本要素,玩家要在敌人放出的大量子弹(弹幕)的细小空隙间闪避,能在玩家闪躲弹幕的时候给玩家带来快感,接近满屏的子弹,增加了对玩家的视觉冲击力 ...

  8. Guava学习笔记:Optional优雅的使用null

    在我们学习和使用Guava的Optional之前,我们需要来了解一下Java中null.因为,只有我们深入的了解了null的相关知识,我们才能更加深入体会领悟到Guava的Optional设计和使用上 ...

  9. [C#.NET 拾遗补漏]08:强大的LINQ

    大家好,这是 [C#.NET 拾遗补漏] 系列的第 08 篇文章,今天讲 C# 强大的 LINQ 查询.LINQ 是我最喜欢的 C# 语言特性之一. LINQ 是 Language INtegrate ...

随机推荐

  1. Rocket - tilelink - RAMModel

    https://mp.weixin.qq.com/s/9ccDTm6HytvfGN5R2CPoAQ   简单介绍RAMModel的实现.   ​​   1. 基本介绍   RAMModel用于定义内存 ...

  2. jchdl - RTL实例 - And2(结构体的使用)

    https://mp.weixin.qq.com/s/qTgeBF9N0mx5UK3xWDb3jg   jchdl对Verilog做了增强,增加了用户自定义结构体类型.使用自定义结构体,可以对输入和输 ...

  3. Kubernetes笔记(四):详解Namespace与资源限制ResourceQuota,LimitRange

    前面我们对K8s的基本组件与概念有了个大致的印象,并且基于K8s实现了一个初步的CI/CD流程,但对里面涉及的各个对象(如Namespace, Pod, Deployment, Service, In ...

  4. Java实现欧拉筛与花里胡哨求质数高级大法的对比

    我也不清楚这是什么高级算法,欧拉筛是昨天有位大佬,半夜无意间告诉我的 欧拉筛: 主要的含义就是我把这个数的所有倍数都弄出来,然后下次循环的时候直接就可以跳过了 import java.text.Sim ...

  5. 【Spring注解驱动开发】使用@Scope注解设置组件的作用域

    写在前面 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象.如果每次 ...

  6. 程序员实用JDK小工具归纳,工作用得到

    在JDK的安用装目录bin下,有一些有非常实用的小工具,可用于分析JVM初始配置.内存溢出异常等问题,我们接下来将对些常用的工具进行一些说明. JDK小工具简介 在JDK的bin目录下面有一些小工具, ...

  7. IP 代理池

    https://github.com/jhao104/proxy_pool 安装依赖 pip install -r requirements.txt 配置 Config/setting.py # Co ...

  8. 1.Go 开始搞起

    link 1. IDE Go Land 服务器激活 2. 资源 中文网站 翻译组 翻译组wiki 待认领文章 入门指南 中文文档 fork 更新 github 中如何定期使用项目仓库内容更新自己 fo ...

  9. Docker学习 ,超全文档!

    我们的口号是:再小的帆也能远航,人生不设限!!        一.学习规划: Docker概述 Docker安装 Docker命令 Docker镜像 镜像命令 容器命令 操作命令 容器数据卷  Doc ...

  10. Pikachu的暴力破解演示-----基于表单的暴力破解

    1 首先打开XAMMP与burpsuite 2 打开游览器输入127.0.0.1:88进入pikachu,(由于我的端口有80改成88所以输入127.0.0.1:88要是没有更改80只需要输入127. ...