网站首页 > 开源技术 正文
在 Java 中,Optional是从 Java 8 开始引入的一个类,用于解决空指针异常的问题。它提供了一种更安全、更优雅的方式来处理可能为空的值。以下是关于Optional的用法介绍以及其优点:
创建 Optional 对象
- ofNullable(T value)可以传入一个可能为 null 的值来创建Optional对象。如果传入的值不为 null,则返回一个包含该值的Optional对象;如果传入的值为 null,则返回一个空的Optional对象。例如:
// 创建一个可能为 null 的字符串的 Optional 对象
Optional<String> optionalStr = Optional.ofNullable(null);
// 创建一个值为 10 的整数的 Optional 对象
Optional<Integer> optionalInt = Optional.ofNullable(10);
- of(T value)传入一个非 null 的值来创建Optional对象。如果传入的值为 null,则会抛出NullPointerException异常。例如:
// 创建一个值为 "Hello" 的字符串的 Optional 对象
Optional<String> optionalStr = Optional.of("Hello");
判断 Optional 对象是否包含值
- isPresent()用于检查Optional对象是否包含非 null 的值。如果包含值,则返回true;否则,返回false。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 判断 Optional 对象是否包含值,如果包含则打印相应信息
if (optionalStr.isPresent()) {
System.out.println("Optional contains a value.");
} else {
System.out.println("Optional is empty.");
}
- isEmpty()从 Java 11 开始引入,用于检查Optional对象是否为空。如果为空,则返回true;否则,返回false。例如:
Optional<String> optionalStr = Optional.ofNullable(null);
// 判断 Optional 对象是否为空,如果为空则打印相应信息
if (optionalStr.isEmpty()) {
System.out.println("Optional is empty.");
} else {
System.out.println("Optional contains a value.");
}
获取 Optional 对象中的值
- get()如果Optional对象包含非 null 的值,则返回该值;如果Optional对象为空,则会抛出NoSuchElementException异常。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 获取 Optional 对象中的值并打印
String str = optionalStr.get();
System.out.println(str);
- orElse(T other)如果Optional对象包含非 null 的值,则返回该值;如果Optional对象为空,则返回指定的默认值。例如:
Optional<String> optionalStr = Optional.ofNullable(null);
// 如果 Optional 对象为空,则返回 "Default value"
String str = optionalStr.orElse("Default value");
System.out.println(str);
- orElseGet(Supplier<? extends T> other)如果Optional对象包含非 null 的值,则返回该值;如果Optional对象为空,则通过调用指定的Supplier函数来获取默认值。例如:
Optional<String> optionalStr = Optional.ofNullable(null);
// 如果 Optional 对象为空,则通过调用 lambda 表达式生成默认值
String str = optionalStr.orElseGet(() -> "Generated default value");
System.out.println(str);
- orElseThrow(Supplier<? extends X> exceptionSupplier)如果Optional对象包含非 null 的值,则返回该值;如果Optional对象为空,则通过调用指定的Supplier函数来抛出异常。例如:
Optional<String> optionalStr = Optional.ofNullable(null);
try {
// 如果 Optional 对象为空,则通过调用 lambda 表达式抛出异常
String str = optionalStr.orElseThrow(() -> new IllegalArgumentException("Value is null."));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
对 Optional 对象中的值进行操作
- ifPresent(Consumer<? super T> consumer)如果Optional对象包含非 null 的值,则调用指定的Consumer函数来对该值进行操作。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 如果 Optional 对象包含值,则打印该值
optionalStr.ifPresent(str -> System.out.println("Value: " + str));
- map(Function<? super T,? extends U> mapper)如果Optional对象包含非 null 的值,则应用指定的函数对该值进行转换,并返回一个新的Optional对象,包含转换后的结果。如果原始的Optional对象为空,则返回一个空的Optional对象。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 对 Optional 对象中的值进行转换,将字符串转换为其长度的 Optional 对象
Optional<Integer> lengthOptional = optionalStr.map(String::length);
if (lengthOptional.isPresent()) {
System.out.println("Length: " + lengthOptional.get());
}
- flatMap(Function<? super T,Optional<? extends U>> mapper)与map方法类似,但接受一个函数,该函数返回一个Optional对象。如果原始的Optional对象包含非 null 的值,并且函数返回的Optional对象也包含值,则返回这个包含转换后结果的Optional对象;否则,返回一个空的Optional对象。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 对 Optional 对象中的值进行转换,将字符串转换为其长度的 Optional 对象
Optional<Integer> lengthOptional = optionalStr.flatMap(str -> Optional.of(str.length()));
if (lengthOptional.isPresent()) {
System.out.println("Length: " + lengthOptional.get());
}
Optional 的其他常用方法
- filter(Predicate<? super T> predicate)如果Optional对象包含的值满足指定的谓词条件,则返回该Optional对象;否则,返回一个空的Optional对象。例如:
Optional<Integer> optionalInt = Optional.ofNullable(10);
// 对 Optional 对象中的值进行过滤,只保留大于 5 的值
Optional<Integer> filteredOptional = optionalInt.filter(i -> i > 5);
if (filteredOptional.isPresent()) {
System.out.println("Filtered value: " + filteredOptional.get());
}
- stream()如果Optional对象包含值,则返回一个包含该值的单元素流;如果Optional对象为空,则返回一个空流。例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 将 Optional 对象中的值转换为流进行操作
optionalStr.stream().forEach(System.out::println);
Optional 如何处理空指针异常
Optional通过以下方式来处理空指针异常:
- 避免直接访问可能为 null 的值传统的方式中,如果直接访问一个可能为 null 的变量,很容易引发空指针异常。而使用Optional,可以避免直接访问可能为 null 的值,而是通过Optional对象提供的方法来安全地获取值。例如,假设我们有一个方法返回一个可能为 null 的字符串:
public String getNullableString() {
return null;
}
- 如果直接访问这个返回值,可能会引发空指针异常:
String str = getNullableString();
System.out.println(str.length()); // 可能抛出空指针异常
- 但是,如果使用Optional来包装这个返回值,就可以安全地处理可能为 null 的情况:
Optional<String> optionalStr = Optional.ofNullable(getNullableString());
optionalStr.ifPresent(str -> System.out.println(str.length())); // 如果字符串不为 null,则打印长度,否则不执行任何操作
- 提供明确的空值处理方式Optional提供了多种方法来处理空值情况,例如orElse、orElseGet和orElseThrow等。这些方法可以让开发者明确地指定在值为空时应该采取的行动,而不是在运行时意外地遇到空指针异常。例如,如果我们希望在值为空时返回一个默认值,可以使用orElse方法:
Optional<String> optionalStr = Optional.ofNullable(getNullableString());
String str = optionalStr.orElse("Default value");
System.out.println(str);
- 如果我们希望在值为空时通过一个函数生成默认值,可以使用orElseGet方法:
Optional<String> optionalStr = Optional.ofNullable(getNullableString());
String str = optionalStr.orElseGet(() -> "Generated default value");
System.out.println(str);
- 如果我们希望在值为空时抛出一个异常,可以使用orElseThrow方法:
Optional<String> optionalStr = Optional.ofNullable(getNullableString());
try {
String str = optionalStr.orElseThrow(() -> new IllegalArgumentException("Value is null."));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
ifPresentOrElse 方法
ifPresentOrElse方法是在 Java 9 中引入的,它允许在Optional对象包含值时执行一个操作,在值为空时执行另一个操作。
例如:
Optional<String> optionalStr = Optional.ofNullable("Hello");
// 如果 Optional 对象包含值,则打印该值,否则打印 "Optional is empty."
optionalStr.ifPresentOrElse(str -> System.out.println("Value: " + str), () -> System.out.println("Optional is empty."));
optionalStr = Optional.ofNullable(null);
// 如果 Optional 对象包含值,则打印该值,否则打印 "Optional is empty."
optionalStr.ifPresentOrElse(str -> System.out.println("Value: " + str), () -> System.out.println("Optional is empty."));
这个方法提供了一种更简洁的方式来处理Optional对象的空值情况,相比于使用ifPresent和orElse方法的组合更加直观。
Optional 的优点
- 明确的空值处理Optional强制开发者显式地处理可能为空的值,使得代码更加清晰地表达了对空值的预期和处理方式。这有助于减少由于意外的空指针异常而导致的错误,提高代码的可靠性。例如,使用orElse、orElseGet和orElseThrow等方法,开发者可以明确地指定在值为空时应该采取的行动,而不是依赖于隐式的空值处理。
- 安全的方法调用链Optional的方法可以安全地链接在一起,形成一个方法调用链。如果任何一个环节的Optional对象为空,整个调用链会立即停止执行,而不会引发空指针异常。例如,可以使用map和flatMap方法对Optional对象中的值进行转换和操作,而不用担心空指针异常的问题。
- 更好的代码可读性使用Optional可以使代码更加清晰地表达其意图,提高代码的可读性。其他开发者在阅读代码时,可以更容易地理解哪些值可能为空,以及如何处理这些空值情况。例如,当看到一个方法返回一个Optional对象时,开发者可以立即知道这个方法可能返回一个空值,并且需要进行适当的处理。
- 鼓励良好的编程习惯Optional鼓励开发者在编写代码时更加谨慎地处理空值情况,避免依赖于不可靠的假设。这有助于提高代码的质量和可维护性。例如,开发者在调用可能返回空值的方法时,会更加倾向于使用Optional来包装返回值,并进行适当的空值处理,而不是直接假设返回值不为空。
Optional提供了一种更安全、更优雅的方式来处理可能为空的值,避免了空指针异常的问题。它具有明确的空值处理、安全的方法调用链、更好的代码可读性和鼓励良好的编程习惯等优点。通过合理地使用Optional的各种方法,可以使代码更加健壮和易于维护。
猜你喜欢
- 2024-09-28 为什么JDK1.8要对HashMap进行红黑树的改动?
- 2024-09-28 程序员:JDK的安装与配置(完整版)(jdk软件安装教程)
- 2024-09-28 大数据分析:学习工具JDK,在线安装指南
- 2024-09-28 JDK 14 调试神器了解一下?| 原力计划
- 2024-09-28 下个月,java要开启收费模式了,你怕了吗?
- 2024-09-28 JDK11升级JDK17最全实践干货来了(jdk11版本)
- 2024-09-28 JDK、JRE和JVM的区别与相互之间的联系
- 2024-09-28 Fury:一个基于JIT动态编译的高性能多语言原生序列化框架
- 2024-09-28 JDK 各版本(1~14)特性总结(jdk各个版本发布时间表)
- 2024-09-28 探索Java的起点:JDK是什么以及如何选择适合你的版本
你 发表评论:
欢迎- 03-19基于layui+springcloud的企业级微服务框架
- 03-19开箱即用的前端开发模板,扩展Layui原生UI样式,集成第三方组件
- 03-19SpringMVC +Spring +Mybatis + Layui通用后台管理系统OneManageV2.1
- 03-19SpringBoot+LayUI后台管理系统开发脚手架
- 03-19layui下拉菜单form.render局部刷新方法亲测有效
- 03-19Layui 遇到的坑(记录贴)(layui chm)
- 03-19基于ASP.NET MVC + Layui的通用后台开发框架
- 03-19LayUi自定义模块的定义与使用(layui自定义表格)
- 最近发表
-
- 基于layui+springcloud的企业级微服务框架
- 开箱即用的前端开发模板,扩展Layui原生UI样式,集成第三方组件
- SpringMVC +Spring +Mybatis + Layui通用后台管理系统OneManageV2.1
- SpringBoot+LayUI后台管理系统开发脚手架
- layui下拉菜单form.render局部刷新方法亲测有效
- Layui 遇到的坑(记录贴)(layui chm)
- 基于ASP.NET MVC + Layui的通用后台开发框架
- LayUi自定义模块的定义与使用(layui自定义表格)
- Layui 2.9.11正式发布(layui2.6)
- Layui 2.9.13正式发布(layui2.6)
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)