我的编程空间,编程开发者的网络收藏夹
学习永远不晚

【Java基础教程】(三十一)常用类库篇 · 第一讲:Optional类——解锁Java的Optional操作,消灭那些隐匿的空指针,还程序世界一个安稳!~

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

【Java基础教程】(三十一)常用类库篇 · 第一讲:Optional类——解锁Java的Optional操作,消灭那些隐匿的空指针,还程序世界一个安稳!~

在这里插入图片描述

1️⃣ 概念

Optional 类是Java 8引入的新特性,旨在解决空值(null)的处理问题。它的设计目的是为了提供一种更好的方式来处理可能为空的值,避免使用null导致空指针异常。

Optional是一个容器对象,可以持有某个类型的非空值或者空值。它是一个包装类,用于替代可能为空的引用变量。

下面是Optional类的几个特征:

  • Optional 可以持有非空的值或空值;
  • 通过一系列方法,可以对 Optional对象进行操作和转换;
  • Optional 提供了一套简洁的API,方便进行空值处理。

2️⃣ 优势和缺点

优点

  • 提高代码的可读性和可维护性,明确表达值可能为空的语义;
  • 强制开发人员显式地处理空值情况,避免了空指针异常。

缺点

  • 可能引入一些额外的代码复杂性,增加代码量。

3️⃣ 使用

3.1 常用操作API

Java的Optional使用流程如下:

  1. 创建Optional对象:

    • 使用Optional.ofNullable(value)创建一个Optional对象,并将value作为包装值,value可以是null
    • 使用Optional.of(value)创建一个Optional 对象,并将 value作为包装值,value不能为null,否则会抛出NullPointerException
  2. 判断Optional对象是否包含值:

    • 使用optional.isPresent()方法判断 Optional 对象是否包含非空值。
      - 使用optional.isEmpty()方法判断Optional对象是否为空。
  3. 获取Optional对象的值:

    • 使用optional.get()方法获取对象中的值。如果Optional对象包含值,返回该值;否则抛出NoSuchElementException异常。
  4. 使用默认值:

    • 使用optional.orElse(defaultValue)方法获取Optional对象的值。如果对象包含值,则返回该值;否则返回指定的默认值。
    • 使用optional.orElseGet(supplier)方法获取Optional对象的值。如果对象包含值,则返回该值;否则使用供应商函数生成一个值并返回。
  5. 条件过滤:

    • 使用optional.filter(predicate)方法根据条件过滤 Optional对象。匹配的话返回当前对象,否则返回空的Optional对象。
  6. 转换值类型:

    • 使用optional.map(mapper)方法将Optional 对象中的值转换为mapper函数的结果,并返回新的对象。
    • 使用optional.flatMap(mapper)方法类似 map操作,但是返回的是 mapper函数所返回的Optional对象本身。
  7. 其他常用方法:

    • 使用optional.ifPresent(consumer)方法,如果Optional对象包含值,则执行传入的操作。
    • 使用optional.orElseThrow()方法,获取Optional对象的值,如果Optional对象包含值,则返回该值;否则抛出NoSuchElementException异常。

在使用Optional 时,应根据具体场景选择合适的方法进行操作。在链式调用中,可以通过一系列的 Optional 操作来进行连续、安全和可读性更高的调用流程,处理可能为空的值。

此外,使用Optional 还需要注意谨慎使用get()方法获取对象的值,最好使用更安全的方法如ifPresentorElse等进行值的处理,以避免空指针异常的发生。

Java的 Optional类中全部的操作方法API汇总如下表:

方法名说明
boolean isPresent()判断Optional对象是否包含值。如果Optional对象包含非空值,返回true;否则返回false
ifPresent(Consumer consumer)如果Optional对象包含值,则执行传入的操作
T get()如果Optional对象包含值,返回该值;否则抛出NoSuchElementException异常
T orElse(T other)获取Optional对象的值,若不存在则返回默认值other
T orElseGet(Supplier other)获取Optional对象的值,若不存在则使用提供的Supplier生成一个新值并返回
T orElseThrow()获取Optional对象的值,若不存在则抛出NoSuchElementException异常
Optional filter(Predicate predicate)如果Optional对象包含值且满足条件,则返回当前Optional对象;否则返回空的Optional对象
map(Function mapper)对Optional对象中的值进行映射操作,返回新的Optional对象
flatMap(Function> mapper)类似map操作,但返回的是mapper函数所返回的Optional对象本身

3.2 案例

下面是一个Java案例程序,演示了如何使用上述每个方法:

import java.util.NoSuchElementException;import java.util.Optional;import java.util.function.Predicate;import java.util.function.Supplier;public class OptionalExample {    public static void main(String[] args) {        // 定义字符串        String value1 = "Hello, world!";        String value2 = null;        // 1、创建Optional对象,并将字符串作为包装值        Optional optional1 = Optional.ofNullable(value1);        Optional nullOpt = Optional.ofNullable(value2);                // 2、创建Optional对象,并将字符串作为包装值。注意这种方式下,value不能为null,否则会抛出NullPointerException        Optional optional2 = Optional.of("Hello, Java!");        //value为null,会抛出NullPointerException        try {            nullOpt = Optional.of(value2);        }catch (NullPointerException e){            System.out.println(e);        }        // 3、创建一个空的Optional对象        Optional optional = Optional.empty();        System.out.println("\n" + optional);                // 4、判断Optional对象是否包含非空值        System.out.println("\nIs optional1 present? " + optional1.isPresent());        System.out.println("Is nullOpt present? " + nullOpt.isPresent());                // 5、获取Optional对象中的值,如果不存在则抛出NoSuchElementException异常        String result1 = optional1.get();        System.out.println("\nValue of optional1: " + result1);        try {            String tempResult = nullOpt.get();            System.out.println("Value of nullOpt: " + tempResult);        }catch (NoSuchElementException e){            System.out.println(e);        }        // 6、获取Optional对象的值,若不存在则返回指定的默认值        String result2 = optional2.orElse("Default Value");        System.out.println("\nValue of optional2: " + result2);        String defaultResult = nullOpt.orElse("Default Value");        System.out.println("Value of nullOpt: " + defaultResult);        // 7、获取Optional对象的值,若不存在则使用提供的Supplier生成一个新值        Supplier other = () -> "Generated Value";        String result3 = optional2.orElseGet(other);        System.out.println("\nValue of optional2: " + result3);        String generatedResult = nullOpt.orElseGet(other);        System.out.println("Value of nullOpt: " + generatedResult);                // 8、根据条件过滤Optional对象,返回满足条件的Optional对象        Predicate predicate = s -> s.length() > 10;        Optional filteredOptional = optional1.filter(predicate);        System.out.println("\nFiltered optional1: " + filteredOptional);        filteredOptional = nullOpt.filter(predicate);        System.out.println("Filtered nullOpt: " + filteredOptional);                // 9、将Optional对象中的值转换为mapper函数的结果,并返回新的Optional对象        Optional lengthOptional = optional1.map(String::length);        System.out.println("\nLength of optional1: " + lengthOptional.orElse(0));                // 10、类似map操作,返回的是mapper函数所返回的Optional对象本身        Optional flatMappedOptional = optional1.flatMap(s -> Optional.of(s.toUpperCase()));        System.out.println("\nFlattened and mapped optional1: " + flatMappedOptional.orElse(""));                // 11、如果Optional对象包含值,则执行传入的操作        System.out.println();        optional2.ifPresent(System.out::println);        // 12、获取Optional对象的值,若不存在则抛出自定义的异常        try {            String result = optional.orElseThrow(() -> new Exception("Exception: Value is not present"));            System.out.println("\nValue of optional: " + result);        }catch (Exception e) {            System.out.println("\n" + e.getMessage());        }    }}

运行结果如下:

java.lang.NullPointerExceptionOptional.emptyIs optional1 present? trueIs nullOpt present? falseValue of optional1: Hello, world!java.util.NoSuchElementException: No value presentValue of optional2: Hello, Java!Value of nullOpt: Default ValueValue of optional2: Hello, Java!Value of nullOpt: Generated ValueFiltered optional1: Optional[Hello, world!]Filtered nullOpt: Optional.emptyLength of optional1: 13Flattened and mapped optional1: HELLO, WORLD!Hello, Java!Exception: Value is not present

3.3 使用技巧

使用Optional 时可以考虑以下几点优化技巧:

  1. 尽量不要在方法参数或返回类型中使用 OptionalOptional主要用于局部变量和字段,以表明其可能为空;
  2. 尽量避免使用optional.get()方法获取 Optional 对象的值,可以使用ifPresent()orElse()等更安全的方法来处理值的情况;
  3. 谨慎使用嵌套Optional,避免过度复杂化逻辑。

4️⃣ 应用场景

常见的应用场景包括:

  • 避免null处理:Optional可以使得代码更加清晰明确,避免因为忽略处理空值而导致空指针异常;
  • 方法返回值:用于替代可能为空的返回值,以便提供更好的可读性;
  • 链式调用:通过一系列的Optional操作,可以进行连续且安全的调用链。

结合实际生产应用来说,Optional在以下业务场景可以发挥重要的作用:

  • 处理外部API调用,当返回值可能为空时使用Optional来封装;
  • 解析JSON对象时,若某些字段为可选字段,可使用Optional来处理;
  • 在数据库查询中,如果结果可能为空,可以使用Optional处理。

5️⃣ 实现原理

Optional类是一个常规的、泛型化的类,通过包装值的方式来处理可能为空的情况。它采用了一些与空对象模式相关的思想,Optional类提供了一组丰富的操作方法,以便更方便地处理可选值,避免了使用空对象时的空指针异常。

Optional类的设计灵感之一可以类比为空对象模式(Null Object Pattern)。
在空对象模式中,需要处理某个操作的对象可能为空,而使用空对象作为代替,以避免空指针异常。
对于Optional类来说,当value字段为null时,表示该Optional对象为空,它也被视作特殊的空对象。

Optional类内部有一个私有字段value,用于存储包装的值。value字段的类型是泛型T,即可以是任何类型的值。如果Optional对象包含一个非空值,则value字段存储这个值;如果Optional对象为空,则value字段为null。

🌾 总结

Optional类是Java 8引入的强大工具,用于解决空值处理问题。它可以用于包装可能为空的引用,提供一种更优雅且可读性更高的方式来表示和处理可能为空的值。使用Optional类,我们可以明确表达值是可空的,并通过一系列简单的操作方法来避免潜在的空指针异常。

尽管Optional并不适用于所有情况,但在正确的场景下,它可以大大提高代码的可读性和可维护性。然而,需要谨慎使用Optional,避免过度使用,以免引入额外的复杂性。了解Optional的基础和高级语法、Java操作API以及实现原理等方面的知识,将有助于正确地应用和优化Optional,从而编写更稳健的Java代码。


温习回顾上一篇(点击跳转)《【Java基础教程】(三十)Java新特性篇 · 第十讲: Stream流——释放流式编程的效率与优雅,狂肝万字只为透彻讲清 Stream流!~》

继续阅读下一篇(点击跳转)《【Java基础教程】(三十二)常用类库篇 · 第二讲:包装类 Wrapper Class——概念及用途, 自动装箱与拆箱,常用操作方法~》

来源地址:https://blog.csdn.net/LVSONGTAO1225/article/details/131391900

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

【Java基础教程】(三十一)常用类库篇 · 第一讲:Optional类——解锁Java的Optional操作,消灭那些隐匿的空指针,还程序世界一个安稳!~

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

【Java基础教程】(三十一)常用类库篇 · 第一讲:Optional类——解锁Java的Optional操作,消灭那些隐匿的空指针,还程序世界一个安稳!~

Java基础教程之常用类库 · Optional类 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 常用操作API3.2 案例3.3 使用技巧 4️⃣ 应用场景5️⃣ 实现原理🌾 总结 1️⃣ 概念 O
2023-08-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录