Optional 理解

1. 含义

Optional 是一个容器对象,该容器里可能包含非空值也可能不包含非空值。最主要的用途就是为了规避 NPE 异常(传入的对象为 null 造成)。

  • 如果存在值,通过 isPresent 方法返回 true,通过 get 方法获取 value

Optional 也提供了额外的方法,这些方法根据是否存在 value 来发挥作用。

注意

请不要在 Optional 对象中使用 hashcodesynchronized== ,否则会产生不可预料的影响。因为 Optional 是基于值的类。

基于值的类(Value-based Classes)

关于什么是 Value-based Clases,我找到 Oracle 的一篇官方文档:Value-based Classes

某些类(如 java.util.Optional 和 java.time.LocalDateTime) 是基于值的。基于值的实例有如下特征:

  • 具有 final 属性,是不可更改的(尽管可能包含对可变对象的引用)
  • 具有 equals()hashCode()toString() 方法的实现,且实现方法仅依赖于实例自身的状态发生变化,而不依赖外部的对象或变量的状态
  • 不使用身份敏感的操作,使用 == 比较两个实例,使用 hashcode 获取实例信息,使用 synchronized 获取内部锁
  • 两实例是否相同是根据 equals() 方法而不是 ==
  • 没有公开的构造方法,而是通过工厂方法(Factory method)来产生实例
  • 若两实例相同,则可以互相替代,且不会有不同的行为

2. Optional 类中方法

2.1 构造方法
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
  • Optional 是一个容器,容器里面包着一个值,这个值是泛型

  • 因为构造方法私有化,所以不能通过 new 新建 Optional 对象,只能通过静态工厂方法构造对象

2.2 创建 Optional 对象方法
  • of:返回一个容器的值不为 null 的对象,使用该方法要求调用者调用 of 方法时,参数值不为空,否则会抛出 NPE 异常。

    public static <T> Optional<T> of(T value) {
    return new Optional<>(value);
    }
  • ofNullable:构造一个可能为空,也可能不为空的 optional 对象。

    public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
    }
  • empty:返回容器的值为 null 的对象

    public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
    }
2.3 其他方法
  • isPresent:判断该对象是否存在

  • get:获取容器的值

  • orElse:容器值不为空,将 value 打印出来;为空,返回指定值。

    public T orElse(T other) {
    return value != null ? value : other;
    }
  • orElseGet:该方法不接受参数。容器值不为空,返回 value;为空,返回指定值

    public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
    }

    举例:

    System.out.println(optional.orElseGet(() -> "nihao"));
  • orElseThrow:容器值不为空,返回 value;为空,抛出异常。

  • map:映射,将一个值映射成另一个值。如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null ,则创建包含映射返回值的 Optional 作为 map 方法返回值,否则返回空 Optional

    public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
    return empty();
    else {
    return Optional.ofNullable(mapper.apply(value));
    }
    }

    举例:

    System.out.println(optional.map(thecompant -> theCompany.getEmployees()).
    orElse(Collections.emptylist()));

注意

在企业开发中,我们经常通过 orElse 来规避 NPE 异常。

3. Optional 对象不应该作为方法参数

Optional 无法被序列化。所以不要试图将 Optional 作为方法参数进行定义,也不要在类当中声明 Optional 类型的成员变量。Optional 通常只作为方法的返回值,用来规避空指针异常。

在使用 Optional 时,应该使用函数式的编程风格。

Optional 理解的更多相关文章

  1. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  2. Swift-可选值(Optional)讲解

    前提:Swift中有规定:对象中的任何属性在创建时,都必须要有明确的初始化值 1.定义可选类型 方式一:常规方式(不常用) var name : Optional<String> = ni ...

  3. map和flatmap的区别+理解、学习与使用 Java 中的 Optional

    转自:map和flatmap的区别 对于stream,   两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...

  4. 理解、学习与使用 Java 中的 Optional

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...

  5. 理解、学习与使用 JAVA 中的 OPTIONAL<转>

    从 Java 8 引入的一个很有趣的特性是 Optional  类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...

  6. 理解、学习与使用Java中的Optional

    从Java8 引入的一个很有趣的特性是Optional类.Optional类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异 ...

  7. 理解、学习与使用 JAVA 中的 Optional【转载】

    这是一篇转载的文章.刚学java的时候看了好久这个Optional,但一直是懵的.今天又又遇到了,重新回来再看的时候,发现并没有那么难道那个. 转载的文章再开头处写了一个对于理解Optional很关键 ...

  8. Optional的理解和使用

    1.Optional 到底是什么? Optional 是一个包装类.类中包装的对象可以为 NULL 或非 NULL.简单说就是把 NULL 包了一层,防止直接对 NULL 操作报NPE. 2.Opti ...

  9. 理解Docker(4):Docker 容器使用 cgroups 限制资源使用

    本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

随机推荐

  1. Hibernate 关系配置

    表之间关系 1. 一对多 一个部门有多个员工,一个员工只能属于某一个部门 一个班级有多个学生,一个学生只能属于一个班级 2. 多对多 一个老师教多个学生,一个学生可以被多个老师教 一个学生可以先择多门 ...

  2. 虚拟机VMware安装及Linux系统基础配置(CentOS 7)

    PS: 我是 VMware 14 安装 CentOS 7 来配置Linux虚拟机,想要安装 Ubuntu 18.04 的可以自行其他搜或者参考博客:https://blog.csdn.net/gith ...

  3. raid卷性能测试

    #RAID卷 独立磁盘冗余阵列RAID是一种把多块独立的硬盘(物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能和提供数据备份技术.组成磁盘阵列的不同方式成为R ...

  4. pom.xml中properties作用

    可以在properties下声明相应的版本信息,然后在dependency下引用的时候用${spring-version}就可以引入该版本jar包了 <properties> <sp ...

  5. OpenJudge计算概论-细菌实验分组

    /*====================================================细菌实验分组总时间限制: 1000ms 内存限制: 65536kB描述有一种细菌分为A.B两 ...

  6. 使用docker运行mysql

    以前开发的时候都是用本地的sqlite开发,但是极少数情况下,sqlite支持的语法发布到服务器上链接mysql会报错. 为了避免这种现象,还是链接本地mysql开发还是更稳定的, 可是开发的项目多了 ...

  7. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_03-用户认证-认证服务查询数据库-查询用户接口-接口定义

    1.2.4 查询用户接口 完成用户中心根据账号查询用户信息接口功能. 在ucenter这个服务里面定义查询用户信息的接口 这个接口在auth的服务的loadUserByUserName这个方法里面被调 ...

  8. spring整合atomikos实现分布式事务

    前言 Atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器,主要用于处理跨数据库事务,比如某个指令在A库和B库都有写操作,业务上要求A库和B库的写操作要具有原子性,这时候就可以用到 ...

  9. iframe重定向让父页面跳转

    情景描述 我们在使用一些后台程序的html模板(比如H-ui)的时候,这些html前端程序是iframe版的, 也就是说在使用的时候,每当我点击左侧导航栏的一个按钮,在右侧就会弹出一个菜单栏,在显示的 ...

  10. KMeans聚类

    常用的聚类方法: ①分裂方法: K-Means算法(K-平均).K-MEDOIDS算法(K-中心点).CLARANS算法(基于选择的算法) ②层次分析方法: BIRCH算法(平衡迭代规约和聚类).CU ...