带你看懂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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值