ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

带你看懂Optional

2021-10-01 20:58:25  阅读:155  来源: 互联网

标签:返回 非空 调用 private value Optional


概述

  • 1、JDK8最大的一个亮点就是引入了Optional类来解决NPE(NullPointerException)
  • 2、阿里开发手册上也推荐使用Optional类来防止NPE
  • 3、综上所述,解决NPE正是Optional类的功能,也是JDK8的一份亮点

Optional预览

  • 1、Optional类的声明
    • 1)被声明为final,即不可被继承
    • 2)使用泛型T,即指定Optional所包含对象的类型
    public final class Optional<T>
  • 2、Optional类的重要属性
    • 1)final类型的value,正是Optional包含对象,其中的T为创建Optional时通过泛型指定的类型
    • 2)全局静态常量EMPTY,调用的是Optional类的无参构造,其中代表value置为空
    private final T value;

	private static final Optional<?> EMPTY = new Optional<>();
  • 3、Optional类的构造方法
    • 可以看出,Optional的两个构造方法均被声明为private——代表外界不可通过new创建Optional对象,即一般在其内部自身使用
    private Optional() {
        this.value = null;
    }

    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

Optional初探——API

MethodsParamsReturnPurposeTheoryFrequency
empty()Optional<T>将Optional的value置空将全局静态常量EMPTY强转为对应的T类型Optional,之后进行返回occasional
of()T类型变量Optional<T>创建一个包含value的Optional对象调用Optional有参构造方法,将传递的变量赋给valueoften
ofNullable()T类型变量Optional<T>创建一个包含value的Optional对象先判断value是否为空
value为空,直接调用empty方法返回空Optional对象
value非空,调用of方法返回一个非空包含value的Optional对象
always
get()T类型变量获取Optional中的value
注意:一般需要先调用isPresent判断value非空
当前value为空,则抛出NoSuchElementException
否则直接返回value
occasional
isPresent布尔型变量判断Optional中的value是否非空直接判断value是否非空occasional
ifPresentConsumer消费型接口对Optional中的value进行指定action当value非空,对value进行指定actionusual
filterPredicate断言型接口Optional<T>对Optional中的value进行指定test调用Objects工具类对传入的断言型接口进行非空校验
调用isPresent方法,当value为空,直接返回当前Optional对象
当value非空,对value进行指定test,断言成功返回当前Optional对象,断言失败调用empty方法返回空Optional对象
often
mapFunction函数型接口Optional<U>对Optional中的value进行指定apply调用Objects工具类对传入的函数型接口进行非空校验
调用isPresent方法,当value为空,直接调用empty方法返回空Optional对象
当value非空,对value进行指定apply,之后调用ofNullable方法对结果封装为新Optional
usual
flatMapFunction函数型接口Optional<U>对Optional中的value进行指定apply
与map类似,但是它不会对结果进行Optional再封装
调用Objects工具类判断传入的函数型接口非空
调用isPresent方法,当value为空,直接调用empty方法返回空Optional对象
当value非空,对value进行指定apply,之后调用Objects工具类对结果进行非空校验
usual
orElseT类型变量T类型变量返回Optional中的value,其中value为空则返回传递的变量判断Optional中value是否为空
value非空则返回value
value为空则返回传递的T类型变量
usual
orElseGetSupplier
供给型接口
T类型变量返回Optional中的value,其中value为空则返回Supplier生产的T类型变量判断Optional中value是否非空
value非空则返回value
value为空则对通过Supplier的get方法生产一个T类型变量返回
usual
orElseThrowSupplier
供给型接口
T类型变量返回Optional中的value,其中value为空则抛出Supplier生产的异常消息判断Optional中value是否非空
value非空则返回value
value为空则对通过Supplier的get方法生产一个异常消息
occasional

Optional深究——Demo

注:此处只研究经常使用的方法,其他的方法也不难理解。

  • 一般都通过ofNullable方法来创建Optional,因为这样既可以接收非Null,又可以接收Null
  • 一般都通过map方法来代替非空判断之后的getter操作
  • 一般都通过orElse方法来获取最后的值,其中一般传入null即可
package com.gezq.optionaldemos;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Optional;

/**
 * Desc: 简单测试Optional
 *
 * @author gezq0714
 * @version MyDemo:1.0.0
 * @email ge051799qi@163.com
 * @date 2021/10/1 - 20:49
 * @since MyDemo:1.0.0
 */
public class Demo {
    public static void main(String[] args) {
        // 假设User是数据库中查询出的一个对象,我们想要获取的是skillName
        User user = new User("gezq", "123456", new Skill("sing", Optional.of("you like sing")));
        // 一般操作
        String skillName1 = null;
        // 1、判断user非空
        if (user != null) {
            // 2、获取skill
            final Skill skill = user.getSkill();
            // 3、判断skill非空
            if (skill != null) {
                // 4、获取skillName
                skillName1 = skill.getSkillName();
            }
        }

        // 使用Optional————使用map获取普通属性的值
        final String skillName2 = Optional.ofNullable(user).map(User::getSkill).map(Skill::getSkillName).orElse(null);
        // 使用Optional——使用flatMap获取被Optional包装过的属性的值
        final String skillIntroduction = Optional.ofNullable(user).map(User::getSkill).flatMap(Skill::getIntroduction).orElse(null);

        System.out.println("一般操作获取skillName:" + skillName1);
        System.out.println("使用Optional获取skillName:" + skillName2);
        System.out.println("使用Optional获取skillIntroduction:" + skillIntroduction);
        /*
            输出结果如下所示:
            一般操作获取skillName:sing
            使用Optional获取skillName:sing
            使用Optional获取skillIntroduction:you like sing
         */
    }

}

@AllArgsConstructor
@NoArgsConstructor
@Data
class User {
    private String username;
    private String password;
    private Skill skill;
}

@AllArgsConstructor
@NoArgsConstructor
@Data
class Skill {
    private String skillName;
    private Optional<String> introduction;
}

标签:返回,非空,调用,private,value,Optional
来源: https://blog.csdn.net/A13777852949/article/details/120580800

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有