(原)

先看看上面的说明:

  1. /**
  2. * A container object which may or may not contain a non-null value.
  3. * If a value is present, {@code isPresent()} will return {@code true} and
  4. * {@code get()} will return the value.
  5. *Optional是一个容器对象,它可能包含,也可能不包含一个非空的值,如果这个值存在,isPresent方法将返回true,get方法将会返回它本身
  6. * <p>Additional methods that depend on the presence or absence of a contained
  7. * value are provided, such as {@link #orElse(java.lang.Object) orElse()}
  8. * (return a default value if value not present) and
  9. * {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
  10. * of code if the value is present).
  11. *Optional提供一些额外的方法,这些方法依赖于它所包含的对象存在与否,例如orElse如果这个包含的对象不存在,将会返回一个默认值和ifPresent方法,如果包含的值存在,则会执行方法块中的内容
  12. * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
  13. * class; use of identity-sensitive operations (including reference equality
  14. * ({@code ==}), hash code, or synchronization) on instances of
  15. * {@code Optional} may have unpredictable results and should be avoided.
  16. *这是一个基于值的class类,对于同一性(特性)敏感的操作 (包含引用的相等性如:==),同一性的hashcode或者同步等等、对optional实例可能会产生不可预料的结果,这种结果应该被避免。
  17. * @since 1.8
  18. */

  

再看看该类:
public final class Optional<T>
这里一个final类
这是一个基于值的类,上面给出了什么叫基于值,上面给出的链接地址不全,看这里:
http://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html

这里说的是基于值的类需要满足以下几点:
1、 final类型和不可变的(可能会包含可变对象的引用)
2、 有equals、hashCode、toString方法的实现,它是通过实例的状态计算出来的,而并不会通过其它的对象或变量去计算。
3、 不会使用身份敏感的操作,比如在二个实例之间引用相等性、hashCode或者内在的锁。
4、 判断二个值相等仅仅通过equal方法,而不会通过==去判断。
5、 它不提供构造方法,它通过工厂方法创建它的实例,这不保证返回实例的一致性。
6、 当它们相等时,它是可以自由替换的。如果x和y 调用equal方法返回true,那么可以将x和y任意交换,它的结果不会产生任何变化。

然后再回来看Optional,你能看到它是私有的:

  1. private Optional() {
  2. this.value = null;
  3. }

 

在它的所有方法中,如果要创建Optional对象,先看看它常用的三个方法。
empty方法回一个空的 Optional对象。
of方法接收一个T参数,T必需为非null值,返回一个Optional对象。
ofNullable方法接收一个T参数,如果T为null,它会调用empty方法,如果不为null则调用of方法。

再看看这二个方法:
isPresent: 如果这个对象的值不为null返回true,否则返回false。
get:如果这个值存在,则返回这个值,如果这个值为null,则抛出异常。
在使用中,这二个方法基本是成对出现的,下面来看一个例子。

  1. String str = "hello";
  2. Optional<String> strValue = Optional.of(str);
  3.  
  4. System.out.println("part1-------------------");
  5.  
  6. if(str != null){
  7. System.out.println(str);
  8. }
  9.  
  10. System.out.println("part2-------------------");
  11.  
  12. if(strValue.isPresent()){
  13. System.out.println(strValue.get());
  14. }

这里,part1和part2的代码是等价的,Optional还提供了一种更简单的方法
strValue.ifPresent(s -> System.out.println(s));
ifPresent方法接收一个consumer函数式接口(之前介绍过),将自己的非空的逻辑写进去。Optioanal该方法更加简洁。

orElse方法:接收一个参数,如果存在,返回这个值本身,否则返回返回这个参数。
orElseGet方法:接收一个Supplier,如果存在,返回这个值本身,否则返回Supplier
对象。

map方法:接收一个Function,如果Optioanal为null则抛出异常(所以这里创建Optional对象时建议用Optional.ofNullable()),如果为空值则返回空,如果不为空则返回Function的返回值。
(例如:一个对象Obj,有一个List属性,如果List有值,返回List,否则返回空集合,可以这么写(

  1. Parent parent = new Parent();
  2. Optional<Parent> parentVal = Optional.ofNullable(parent);
  3. System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));

Optioanal通常作为方法的返回值来使用,它可以有效的规避返回null的结果,如果一个类需要序列化,当Optional作为参数类型或是成员变量类型是有问题的。因为Optional没有实现序列化,所以Optioanl通常不被建议作为参数或常量使用。

下面给出一些Optional常用的例子:

  1. package com.demo.jdk8;
  2.  
  3. import java.util.Collections;
  4. import java.util.List;
  5. import java.util.Optional;
  6.  
  7. public class Test6 {
  8. public static void main(String[] args) {
  9. String str = "hello";
  10. Optional<String> strValue = Optional.of(str);
  11.  
  12. System.out.println("part1-------------------");
  13.  
  14. if(str != null){
  15. System.out.println(str);
  16. }
  17.  
  18. System.out.println("part2-------------------");
  19.  
  20. if(strValue.isPresent()){
  21. System.out.println(strValue.get());
  22. }
  23.  
  24. System.out.println("part3-------------------");
  25.  
  26. strValue.ifPresent(s -> System.out.println(s));
  27.  
  28. System.out.println("part4-------------------");
  29. Optional<String> op = Optional.ofNullable(null);
  30.  
  31. System.out.println(op.orElse("hahahaha"));
  32. System.out.println("part5-------------------");
  33. Optional<String> opt = Optional.ofNullable("nihao");
  34.  
  35. System.out.println(op.orElseGet(() -> "hehehe"));
  36. System.out.println("part6-------------------");
  37. System.out.println(opt.map(m -> m + "123").orElseGet(() -> "world"));
  38.  
  39. System.out.println("part7-------------------");
  40.  
  41. Parent parent = new Parent();
  42. // List<Object> list = Arrays.asList("张三","李四");
  43. // parent.setList(list);
  44.  
  45. Optional<Parent> parentVal = Optional.ofNullable(parent);
  46. System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));
  47.  
  48. }
  49.  
  50. public void test(Optional optional){
  51.  
  52. }
  53.  
  54. }
  55.  
  56. class Parent{
  57. private List<Object> list;
  58.  
  59. public List<Object> getList() {
  60. return list;
  61. }
  62.  
  63. public void setList(List<Object> list) {
  64. this.list = list;
  65. }
  66. }

  

 例子请看这里:https://github.com/LeeScofield/java8

Java 8 新特性:6-Optional类的更多相关文章

  1. JAVA 8 新特性 __ Optional 类

    Optional 类是一个可以作为null容器的对象,若值存在调用isPresent()就返回 true,调用get()会返回该对象. Optional是一个容器,可以保存类型T的值,或者仅仅保存nu ...

  2. Java 15 新特性:隐藏类

    什么是隐藏类 隐藏类,是一种不能被其他类直接使用的类.引入隐藏类的主要目的是给框架来使用,使得框架可以在运行时生成类,并通过反射间接使用它们.可能有点抽象,不要紧,下面我们通过一个例子来直观的认识它! ...

  3. 【Java8新特性】Optional类在处理空值判断场景的应用 回避空指针异常 编写健壮的应用程序

    一.序言 空值异常是应用运行时常见的异常,传统方式为了编写健壮的应用,常常使用多层嵌套逻辑判断回避空指针异常.Java8新特性之Optional为此类问题提供了优雅的解决方式. 广大程序员朋友对空值异 ...

  4. Java 16 新特性:record类

    以前我们定义类都是用class关键词,但从Java 16开始,我们将多一个关键词record,它也可以用来定义类.record关键词的引入,主要是为了提供一种更为简洁.紧凑的final类的定义方式. ...

  5. java8新特性之Optional类

    NullPointException可以说是所有java程序员都遇到过的一个异常,虽然java从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而java设计者也只能是让指针在java ...

  6. 010-jdk1.8版本新特性二-Optional类,Stream流

    1.5.Optional类 1.定义 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个 ...

  7. Java 8新特性之 Optional(八恶人-5)

    Oswaldo Mobray 莫博瑞·奥斯瓦尔多 “I‘m Oswaldo Mobray, the hangman in these parts.” “我是莫博瑞·奥斯瓦尔多,这片地区的绞刑官.” 一 ...

  8. java8新特性六-Optional 类

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

  9. 【Java8新特性】Optional 类

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

  10. Java 12 新特性介绍,快来补一补

    Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...

随机推荐

  1. ASP.NET Core DI 手动获取注入对象

    ASP.NET Core DI 一般使用构造函数注入获取对象,比如在ConfigureServices配置注入后,通过下面方式获取: private IValueService _valueServi ...

  2. 冗余jar包识别神器 - loose.jar

    冗余jar包识别神器 - loose.jar 场景描述 项目迭代久了,会添加各类jar包,事实上很多jar包其实根本没用到.那如何快速识别冗余的jar,以方便从项目中清除掉呢? 比如: 该简单的测试工 ...

  3. SpringBoot整合系列-整合MyBatis

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9971036.html SpringBoot整合Mybatis 步骤 第一步:添加必要的j ...

  4. 【.NET Core项目实战-统一认证平台】第八章 授权篇-IdentityServer4源码分析

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我介绍了如何在网关上实现客户端自定义限流功能,基本完成了关于网关的一些自定义扩展需求,后面几篇将介绍基于IdentityServer ...

  5. sqlserver数据库发送邮箱

    Exec [msdb].dbo.sp_send_dbmail @profile_name='SQLMailConfig', @recipients = @email,    //需要发送的邮箱 @su ...

  6. Java开发笔记(十六)非此即彼的条件分支

    前面花了大量篇幅介绍布尔类型及相应的关系运算和逻辑运算,那可不仅仅是为了求真值或假值,更是为了通过布尔值控制流程的走向.在现实生活中,常常需要在岔路口抉择走去何方,往南还是往北,向东还是向西?在Jav ...

  7. 编译内核时出现drivers/mfd/mxc-hdmi-core.c:36:24: fatal error: mach/clock.h: No such file or directory

    在学习恩智浦IMX6D开发板时,编译内核出现 drivers/mfd/mxc-hdmi-core.c::: fatal error: mach/clock.h: No such file or dir ...

  8. 前端入门19-JavaScript进阶之闭包

    声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...

  9. 预置第三方apk到MTK项目相关问题总结

    目前5.0之后项目预置方式通用步骤为: 建立apk文件夹;  置目标apk到该文件夹下;   解压缩apk查看是否包含lib/文件夹(apk项目是否包含lib库文件);  在该文件夹下编写Androi ...

  10. myapp——自动生成小学四则运算题目的命令行程序(侯国鑫 谢嘉帆)

    1.Github项目地址 https://github.com/baiyexing/myapp.git 2.功能要求 题目:实现一个自动生成小学四则运算题目的命令行程序 功能(已全部实现) 使用 -n ...