详细分析Java中的Optional类以及应用场景

前言

在实战中学习,灵活运用每个操作类,具体如下:
在这里插入图片描述

1. 基本知识

源码主要如下:

在这里插入图片描述

大致含义如下:

这是一个容器对象,可能包含或不包含非空值。如果有值存在,isPresent() 方法将返回 true,而 get() 方法将返回该值。
提供了一些依赖于包含值的存在或缺失的其他方法,例如 orElse()(如果值不存在,则返回默认值)和 ifPresent()(如果存在值,则执行一段代码块)。
这是一个基于值的类;在 Optional 实例上使用依赖于身份的操作(包括引用相等性(==)、身份哈希码或同步)可能会产生不可预测的结果,应该避免使用。
自 Java 1.8 起。

用开发的角度来讲,该类是 Java 8 中引入的一个用于处理可能为 null 的值的容器类。

它的设计目的是为了解决在代码中频繁出现的空指针异常问题。

不过这个类有好有坏,适当使用即可,其缺点就是造成代码过于冗长(= - = )
最主要是引入额外的对象开销。

了解基本的特性以及薄弱项之后,站在后端的角度灵活运用其API以及常用方法

2. 常用API

创建Optional的对下你个有以下三种方式:

  1. Optional.of(value): 创建一个包含非空值的 Optional 对象
    如果传递的值为 null,会抛出 NullPointerException
Optional<String> nonNullOptional = Optional.of("Hello, World!");
  1. Optional.ofNullable(value): 创建一个 Optional 对象,如果传递的值为 null,仍然会创建一个空的 Optional 对象
Optional<String> optional = Optional.ofNullable(someNullableValue);
  1. Optional.empty(): 创建一个空的 Optional 对象
Optional<String> emptyOptional = Optional.empty();

👇

常用的操作方法如下:

  1. isPresent(): 判断 Optional 对象是否包含非空值
if (optional.isPresent()) {
    // 做一些操作
}
  1. ifPresent(Consumer<? super T> consumer): 如果 Optional 对象包含非空值,则执行传入的操作
optional.ifPresent(value -> System.out.println("Value: " + value));
  1. orElse(T other): 如果 Optional 对象包含非空值,则返回该值;否则返回传入的默认值
String result = optional.orElse("Default Value");
  1. orElseGet(Supplier<? extends T> other): 类似于 orElse,但是默认值是由传入的 Supplier 提供的
String result = optional.orElseGet(() -> generateDefaultValue());
  1. orElseThrow(Supplier<? extends X> exceptionSupplier): 如果 Optional 对象为空,则抛出由传入的 Supplier 提供的异常
String result = optional.orElseThrow(() -> new NoSuchElementException("Value not present"));

👇👇

链式操作:Optional 提供了一些方法,在不解包 Optional 的情况下进行链式操作(这有助于避免空指针异常,并使代码更加清晰)

比如如下例子: nullableValue 不为 null,则将其转换为大写;否则,返回默认值 "Default"

String result = Optional.ofNullable(nullableValue)
                        .map(String::toUpperCase)
                        .orElse("Default");

3. Demo

通过示例的Demo操作上述的方法

import java.util.Optional;
public class Demo {
    public static void main(String[] args) {
        // 示例1: 创建包含非空值的 Optional 对象
        Optional<String> nonNullOptional = Optional.of("码农, 研究僧!");

        // 示例2: 创建可能为空值的 Optional 对象
        String nullableValue = null;
        Optional<String> optional = Optional.ofNullable(nullableValue);

        // 示例3: 使用 isPresent 判断是否包含非空值
        if (nonNullOptional.isPresent()) {
            System.out.println("Non-null value: " + nonNullOptional.get()); // 此处有空值,为true,输出 Non-null value: 码农, 研究僧!
        } else {
            System.out.println("Non-null value is not present.");
        }

        // 示例4: 使用 ifPresent 执行操作,没有空值才会执行!
        nonNullOptional = Optional.of("码农, 研究僧!");
        nonNullOptional.ifPresent(value -> System.out.println("Value from optional: " + value)); // 没有空值,就会输出 Value from optional: 码农, 研究僧!

        // 示例5: 使用 orElse 获取值或默认值
        String result = optional.orElse("Default Value");
        System.out.println("Result from orElse: " + result); // 输出默认值 Result from orElse: Default Value

        // 示例6: 使用 orElseGet 获取值或由 Supplier 提供的默认值
        String resultFromSupplier = optional.orElseGet(() -> generateDefaultValue());
        System.out.println("Result from orElseGet: " + resultFromSupplier); // 输出Supplier提供的默认值

        // 示例7: 使用 orElseThrow 抛出异常
        try {
            String resultOrThrow = optional.orElseThrow(() -> new RuntimeException("Value not present"));
            System.out.println("Result from orElseThrow: " + resultOrThrow);
        } catch (RuntimeException e) {
            System.out.println("Exception caught: " + e.getMessage()); // 此处对象为空,所以输出了这语句 Exception caught: Value not present
        }

        // 示例8: 链式操作
        String chainedResult = Optional.ofNullable(nullableValue)
                .map(String::toUpperCase)
                .orElse("Default Chain");
        System.out.println("Chained result: " + chainedResult); // 输出默认值:Chained result: Default Chain
    }

    private static String generateDefaultValue() {
        return "Default Value from Supplier";
    }
}

截图如下:

在这里插入图片描述

4. 应用场景

应用场景一般用于方法返回值或者集合操作中

场景一

当方法的返回值可能为 null 时,使用 Optional 可以清晰地表达这一点,并要求调用者明确处理可能的空值情况

public Optional<String> findUserById(String userId) {
    // 在数据库中查找用户,可能返回 null
    // 使用 Optional 封装返回值
    // 返回 Optional.ofNullable(user) 或 Optional.empty()
}

场景二

在对集合进行操作时,某些操作可能返回 null(例如在查找元素时)。
使用 Optional 可以更好地处理这些情况,而不是直接返回 null

public Optional<String> findFirstEvenNumber(List<Integer> numbers) {
    // 在集合中查找第一个偶数,可能返回 null
    // 使用 Optional 封装返回值
    // 返回 Optional.ofNullable(evenNumber) 或 Optional.empty()
}

场景三

在防御性编程中,通过使用 Optional 可以更好地处理可能为 null 的值,避免空指针异常

public Optional<String> getUserName(User user) {
    // 获取用户的名称,用户对象可能为 null
    // 使用 Optional 封装返回值
    // 返回 Optional.ofNullable(userName) 或 Optional.empty()
}

场景四:

设计自己的 API 时,如果某个方法的返回值可能为空,使用 Optional 可以使 API 更加健壮和易于理解。

public Optional<Product> findProductById(String productId) {
    // 根据产品ID查找产品,产品可能不存在
    // 使用 Optional 封装返回值
    // 返回 Optional.ofNullable(product) 或 Optional.empty()
}

场景五:

当处理多层嵌套的对象时,使用 Optional 可以避免深层次的 null 检查,使代码更加简洁

public Optional<String> getAddressCity(User user) {
    // 获取用户地址的城市,用户、地址对象可能为 null
    // 使用 Optional 封装返回值
    // 返回 Optional.ofNullable(city) 或 Optional.empty()
}

虽然看起来很新鲜, 可以提高代码的健壮性,但需要注意不要滥用

主要如下,还是重点讲讲:

  1. 造成代码冗长,本来一个null值就可以解决
  2. 引入多一个对象多一个开销,如果本身追求速度,就不用刻意这样
  3. 再者如果嵌套多层对象还这么使用,开发的可能感觉很牛,看的同事可能觉得臭臭臭臭臭

在某些情况下,直接使用 null 可能是更简单和清晰的选择
使用 Optional 主要是为了增加对空值的明确处理,使代码更加防御性和易读

  • 17
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java8Optional是一个容器对象,可以包含null或非null值。它提供了一种优雅的方式来处理null值,避免了NullPointerException异常的出现。Optional可以用于返回值、方法参数和实例变量等场景,使代码更加简洁、清晰和安全。使用Optional可以使代码更加健壮,减少了代码null检查和异常处理,提高了代码的可读性和可维护性。 ### 回答2: OptionalJava 8新引入的一个,它的主要作用是在避免NullPointerException的情况下将null值返回给调用者。这个是一个容器对象,它可以保存非空的对象,也可以保存空值(null)。 Optional提供了通过判断一个对象是否为空来避免空指针异常的方式。它可以在代码替换传统的null判断,这样可以更加方便地编写代码,并且可以使代码更加健壮。 在Java,如果一个方法返回值为null,那么在调用该方法返回值的时候,会有可能抛出NullPointerException异常。而Optional的出现可以帮助我们避免这种情况的出现,在调用Optional的get()方法时,如果Optional保存的对象不为null,就会返回该对象,否则抛出一个NoSuchElementException异常。 Optional还提供了一些方法来简化代码,比如orElse()方法,如果Optional保存的对象不为null,则返回该对象,否则返回指定的default值。还有ifPresent()方法,当Optional保存的对象不为null时,会执行指定的代码,否则不执行。 总之,OptionalJava 8一个很有用的,它可以帮助我们更加方便地处理null值,避免空指针异常的出现,并且可以简化代码。但是需要注意的是,不应该滥用Optional,因为它并不是完美的解决方案,有时候需要对null值进行特殊处理。 ### 回答3: Java 8在语言层面上增加了一个新的Optional。这是一个特殊的容器对象,可以包含一个null或非null的值。 Optional的目的是解决Javanull引用问题。在Java,如果一个变量被赋值为null,而我们试图调用该变量所对应的方法,那么就会出现NullPointerException异常。 使用Optional可以避免这种情况的发生。如果一个变量是Optional对象,那么我们必须显式地检查该对象是否包含非null的值,才能对其进行操作。这样,在我们试图调用该变量所对应的方法之前,就可以避免空指针异常的发生。 Optional提供了很多方法来判断是否有值、获取值、如果没有值则返回默认值等等,使得我们可以更加方便地处理空值。 下面是一些Optional提供的方法: 1. Optional.of(T value):创建一个包含非null值的Optional对象,如果T为null,则抛出NullPointerException异常。 2. Optional.ofNullable(T value):创建一个Optional对象,如果T为null,则该对象为空。 3. Optional.empty():创建一个空的Optional对象。 4. get():如果值存在,则返回该值,否则抛出异常。 5. orElse(T other):如果值存在,则返回该值,否则返回其他默认值。 6. isPresent():返回一个boolean型的值,表示该Optional对象是否包含值。 7. ifPresent(Consumer<? super T> consumer):如果该Optional对象包含值,则对该值执行给定的操作。 在编写Java程序时,我们应该始终努力避免使用null值。使用Optional,可以使得我们的代码更加健壮、可读性更强。但是,过多地使用Optional可能会导致代码过于冗长,所以在使用的过程需要权衡利弊。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值