Optional 理解
Optional 理解
1. 含义
Optional
是一个容器对象,该容器里可能包含非空值也可能不包含非空值。最主要的用途就是为了规避 NPE 异常(传入的对象为 null 造成)。
- 如果存在值,通过
isPresent
方法返回 true,通过get
方法获取 value
Optional
也提供了额外的方法,这些方法根据是否存在 value 来发挥作用。
注意
请不要在 Optional
对象中使用 hashcode
,synchronized
,==
,否则会产生不可预料的影响。因为 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 理解的更多相关文章
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- Swift-可选值(Optional)讲解
前提:Swift中有规定:对象中的任何属性在创建时,都必须要有明确的初始化值 1.定义可选类型 方式一:常规方式(不常用) var name : Optional<String> = ni ...
- map和flatmap的区别+理解、学习与使用 Java 中的 Optional
转自:map和flatmap的区别 对于stream, 两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...
- 理解、学习与使用 Java 中的 Optional
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) -- 每个 Java 程序员都 ...
- 理解、学习与使用 JAVA 中的 OPTIONAL<转>
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
- 理解、学习与使用Java中的Optional
从Java8 引入的一个很有趣的特性是Optional类.Optional类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都非常了解的异 ...
- 理解、学习与使用 JAVA 中的 Optional【转载】
这是一篇转载的文章.刚学java的时候看了好久这个Optional,但一直是懵的.今天又又遇到了,重新回来再看的时候,发现并没有那么难道那个. 转载的文章再开头处写了一个对于理解Optional很关键 ...
- Optional的理解和使用
1.Optional 到底是什么? Optional 是一个包装类.类中包装的对象可以为 NULL 或非 NULL.简单说就是把 NULL 包了一层,防止直接对 NULL 操作报NPE. 2.Opti ...
- 理解Docker(4):Docker 容器使用 cgroups 限制资源使用
本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...
随机推荐
- JS 定时器的4种写法及介绍
JS提供了一些原生方法来实现延时去执行某一段代码,下面来简单介绍一下setTiemout.setInterval.setImmediate.requestAnimationFrame. 一.什么是定时 ...
- JDK安装及Java环境变量配置
1.JDK下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html. 2.点击A ...
- MySQL数据库可以用任意ip连接访问的方法
> use mysql; > update user set host='%' where host='localhost'; > flush privileges;
- ArcGIS 10.5 tensorflow安装日记
ArcGIS 10.5 tensorflow安装日记 商务科技合作:向日葵,135-4855__4328,xiexiaokui#qq.com Datetime: 2019年5月27日星期一 Os: w ...
- iOS12 中的后台下载与上传
严格意义上来说,iOS并不能像Android一样,真的在后台开启一个下载Service,一直下载.但是它可以进行在系统允许范围内的后台上传和下载. 当使用 NSURLSessionConfigurat ...
- Ionic4.x 中的 UI 组件(UI Components) Slides 轮播图组件、Searchbar 组件、 Segment 组件
Slides 轮播图组件 Ionic4.x 中的轮播图组件是基于 swiper 插件,所以配置 slides 的属性需要在 swiper 的 api 中 找 Swiper Api:http://ida ...
- 008-多线程-JUC集合-Queue-LinkedBlockingQueue
一.概述 LinkedBlockingQueue是一个单向链表实现的阻塞队列.该队列按 FIFO(先进先出)排序元素,新元素插入到队列的尾部,并且队列获取操作会获得位于队列头部的元素.链接队列的吞吐量 ...
- 阶段5 3.微服务项目【学成在线】_day07 课程管理实战_02-我的课程-前端页面与Api说明
我的课程列表使用element 的card组件,如下: 前端页面代码 点击新增到了一个新增课程的页面 新增课程的界面 下面的card是循环遍历的代码 写死的card的静态数据 请求服务端的接口拿到数据 ...
- springboot集成调用Azkaban
springboot集成调用Azkaban 一. 说明 1.Azkaban是由Linkedin公司推出的一个批量工作流任务调度器,主要用于在一个工作流内以一个特定的顺序运行一组工作和流程,它的配置是通 ...
- linux 安装网易云音乐
1.首先去官网下载最新的网易云 网易云音乐曾经推出官方Linux版本,提供的下载安装包有:deepin15(32位):http://s1.music.126.net/download/pc/net . ...