首页 > 编程语言 >[Java SE] 核心源码精讲:java.util.Optional(JDK1.8-)

[Java SE] 核心源码精讲:java.util.Optional(JDK1.8-)

时间:2024-08-08 11:30:55浏览次数:13  
标签:返回 JDK1.8 Java String 对象 ofNullable 源码 null Optional

1 概述: java.util.Optional

该类是 Java 8 中引入的一个用于处理可能为 null 的值的容器类。

  • 这是一个容器对象,可能包含或不包含非空值。

  • 自 Java 1.8 起支持

  • 如果有值存在,isPresent() 方法将返回 true;而 get() 方法将返回该值,若无值存在,将报异常java.util.NoSuchElementException: No value present

  • 提供了一些依赖于包含值的存在或缺失的其他方法。例如 orElse()(如果值不存在,则返回默认值)和 ifPresent()(如果存在值,则执行一段代码块)。

  • 这是一个基于值的类;在 Optional 实例上使用依赖于身份的操作(包括引用相等性(==)、身份哈希码或同步)可能会产生不可预测的结果,应该避免使用。

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

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

2 API

对象创建

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

Optional.of(value) : 创建一个包含非空值的 Optional 对象

如果传递的值为 null,会抛出 NullPointerException

Optional<String> nonNullOptional = Optional.of("Hello, World!");

Optional.ofNullable(value): 创建一个 Optional 包装对象,如果传递的值为 null,仍然会创建一个空的 Optional 对象

  • Optional.ofNullableJavajava.util.Optional 类的一个静态方法
public static <T> Optional<T> ofNullable(T value)
  • 其用于返回一个指定值的 Optional 对象。
  • 这个方法的主要作用是将一个可能为 null 的值包装到 Optional 容器中。
  • 如果该值为 null,则返回一个空的 Optional 对象;否则,返回一个包含该值的 Optional 对象。
Optional<String> optional = Optional.ofNullable(someNullableValue);

Optional.empty(): 创建一个空的 Optional 对象

Optional<String> emptyOptional = Optional.empty();

操作方法

isPresent() : 判断 Optional 对象是否包含非空值

if (optional.isPresent()) {
    // 做一些操作
}

ifPresent(Consumer<? super T> consumer): 如果 Optional 对象包含非空值,则执行传入的操作

optional.ifPresent(value -> System.out.println("Value: " + value));

orElse(T other): 如果 Optional 对象包含非空值,则返回该值;否则返回传入的默认值

String result = optional.orElse("Default Value");

orElseGet(Supplier<? extends T> other): 类似于 orElse,但是默认值是由传入的 Supplier 提供的

String result = optional.orElseGet( () -> generateDefaultValue() );

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");

//if String nullableValue = null , then : result = "Default"
//if String nullableValue = "Hello" , then : result = "HELLO"

3 应用场景

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

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

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

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

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

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

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

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

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

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

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

4 注意事项

虽然看起来很新鲜, 可以提高代码的健壮性,但需要注意不要滥用。主要如下,还是重点讲讲:

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

X 参考文献

标签:返回,JDK1.8,Java,String,对象,ofNullable,源码,null,Optional
From: https://www.cnblogs.com/johnnyzen/p/18348594

相关文章

  • Java中一维数组的学习
    一维数组目录一维数组创建数组null数组的遍历for循环遍历数组for-each循环遍历while循环遍历do-while循环遍历数组的反向遍历创建数组Java语言使用new操作符来创建数组,语法如下:arrayRefVar=newdataType[arraySize];上面的语法语句做了两件事:使用dataType[arraySize]......
  • java集成onlyoffice实现文档在线预览编辑
    一、onlyoffice是什么ONLYOFFICE是一款由AscensioSystemSIA公司开发的在线办公软件套件,它提供了文档编辑、电子表格、演示文稿和表单等多种办公工具,旨在提高团队协作效率和文档处理的便捷性。以下是关于ONLYOFFICE的详细介绍:1、软件概述名称:ONLYOFFICE文档(英文名ONLYOFFIC......
  • 如何把Connection 封装到工具类里面 调用工具类方法实现 增删改查操作 java JDBC
    如何把Connection封装到工具类里面调用工具类方法实现增删改查操作javaJDBC使用数据库连接池以HikariCP为例在JDBC中,使用数据库连接池是一个常见的做法,以提高数据库操作的效率和性能。连接池管理着一组数据库连接,这些连接可以被重用而不是每次需要时都创建新的连接。......
  • 如何把Connection 封装到工具类里面 调用工具类方法实现 增删改查操作 java JDBC使用
    如何把Connection封装到工具类里面调用工具类方法实现增删改查操作javaJDBC使用C3P0数据库连接池答:当使用C3P0作为数据库连接池时,你可以按照类似的模式来配置和使用它。以下是一个示例,展示了如何在Java项目中配置C3P0连接池,并创建一个工具类来管理数据库连接和执行基本的......
  • Java基础(十):静态变量、静态方法、代码块、main方法
    Java基础(十):静态变量、静态方法、代码块、main方法文章目录一、类变量/静态变量(static)二、类方法/静态方法(static)三、main方法四、代码块(一)static代码块(二)普通代码块五、属性初始化、代码块、构造器的调用优先级【超级重点】一、类变量/静态变量(static)(一)类变量......
  • java 时间段划分 1.把一个时间段划分为 整天 和非整天的时间段 2. 把List<Loca
     时间段划分  1.把一个时间段划分为整天和非整天的时间段  例如: "2024-07-1108:30:00" ~   "2024-07-2308:30:00";例如 完整的日期:2024-07-122024-07-132024-07-142024-07-152024-07-162024-07-172024-07-182024-07-192024-07-202024-07-21202......
  • 计算机毕业设计-基于Java+SSM架构的珠宝首饰交易平台系统项目开发实战(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......
  • springboot英语学习平台 毕业设计源码89605
                           摘 要随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自己的信息更及时有效地推广出去,而其中最好的方式就是建立网络管理系统,并对其进行信息管理。由于现在网络的发达,......
  • 宏观层面理解Java IO
    什么是IO简单来说就是输入和输出,体现了数据的流动。从不同的视角来看,IO有不同的解释直观层面在日常生活中,键盘鼠标,显示器音响打印机,这些就属于IO设备,人机交互的过程中,需要我们对计算机输入指令,计算机给我们输出内容,声音文字视频等等。计算机视角在计算机视角,任何涉及到CPU与......
  • 视频播放器 源码 资料库 版权信息
     本程序可供个人/企业/学校/政府机关等自由场合任意安装和使用。*注意事项 -本程序受著作权法和软件保护法的保护,除保护法条款中允许或非限制的范围以外,  任何人对本程序进行的逆向工程、反编译、重新组装都将被视为违法。(仅FFmpeg、lame遵循其LGPL协议。) -本程......