怎么使用 Optional 来告别空指针?

简介: Optional`<T>` 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。你可以把Optional对象看成一种特殊的集合数据,它至多包含一个元素。

「Java8系列」神秘的Lambda

「Java8系列」神奇的函数式接口

「Java8系列」流式编程Stream

Optional类入门

Optional<T> 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。你可以把Optional对象看成一种特殊的集合数据,它至多包含一个元素。

常用方法:

  • Optional.of(T t) : 将指定值用 Optional 封装之后返回,如果该值为 null,则抛出一个 NullPointerException 异常。
  • Optional.empty() : 创建一个空的 Optional 实例。
  • Optional.ofNullable(T t) : 将指定值用 Optional 封装之后返回,如果该值为 null,则返回一个空的 Optional 对象。
  • get() : 如果该值存在,将该值用 Optional 封装返回,否则抛出一个 NoSuchElementException 异常。
  • orElse(T t) : 如果调用对象包含值,返回该值,否则返回t。
  • orElseGet(Supplier s) : 如果调用对象包含值,返回该值,否则返回 s 获取的值。
  • orElseThrow() :它会在对象为空的时候抛出异常。
  • map(Function f) : 如果值存在,就对该值执行提供的 mapping 函数调用。
  • flatMap(Function mapper) : 如果值存在,就对该值执行提供的mapping 函数调用,返回一个 Optional 类型的值,否则就返回一个空的 Optional 对象。

注意:Optional类的设计初衷仅仅是要支持能返回Optional对象的语法,并未考虑作为类的字段使用,也没有实现序列化接口,在领域模型中使用Optional,有可能引发程序故障。

使用Optional实战

用Optional封装可能为null的值,我们在项目中很多时候都会遇到,掉一个方法然后返回一个null,最后需要不断的判空。比如获取Map中的不含指定键的值,它的get方法返回的就是一个null。

 //例如:
 Object value = map.get("key");
 
 //使用Optional封装结果后可以这么写:
 Optional<Object> value = Optional.ofNullable(map.get("key"));
 
 /**
 * 如果想在获取为null以后给个默认值,可以这么写:
 * orElse和orElseGet的区别是当Optional的值是空值时,无论orElse还是orElseGet都会执行;而当返回的Optional有值时,orElse会执行,而orElseGet不会执行。
 */
 Object value = Optional.ofNullable(map.get("key")).orElse("value");
 Object value1 = Optional.ofNullable(map.get("key")).orElseGet(()->"value");

由于某种原因,函数无法返回某个值,这时除了返回null,Java API比较常见的替代做法是抛出一个异常。这种情况比较典型的例子是使用静态方法Integer.parseInt(String),将String转换为int。在这个例子中,如果String无法解析到对应的整型,该方法就抛出一个NumberFormatException。最后的效果是,发生String无法转换为int时,代码发出一个遭遇非法参数的信号,唯一的不同是,这次你需要使用try/catch 语句,而不是使用if条件判断来控制一个变量的值是否非空。

你也可以用空的Optional对象,对遭遇无法转换的String时返回的非法值进行建模,这时你期望parseInt的返回值是一个optional。我们无法修改最初的Java方法,但是这无碍我们进 行需要的改进,你可以实现一个工具方法,将这部分逻辑封装于其中,最终返回一个我们希望的 Optional对象,代码如下所示。

public static Optional<Integer> stringToInt(String s) {
try { 
        //如果String能转换为对应的Integer,将其封装在Optioal对象中返回
        return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
        //否则返回一个空的Optional对象
        return Optional.empty();
    }
}

Optional就是讲到这里,这个实在没什么好说的了,大家自己实践吧。

大家看后辛苦点个赞点个关注哦!后续还会后更多的博客。如有错误,烦请指正。
目录
相关文章
|
6月前
|
程序员 编译器 C++
【实用编程技巧】不想改bug?初学者必须学会使用的报错函数assert!(断言函数详解)
【实用编程技巧】不想改bug?初学者必须学会使用的报错函数assert!(断言函数详解)
65 2
|
JavaScript Dubbo Java
还用 if(obj!=null) 做非空判断?带你快速上手 Optional 实战性理解
1.前言 2.认识Optional并使用 3.实战场景再现 4.Optional使用注意事项 5.jdk1.9对Optional优化
|
程序员 C++
智能指针避坑指南——几种常见的错误用法
智能指针避坑指南——几种常见的错误用法
|
6月前
|
存储 安全 编译器
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
332 0
|
安全 Java
Java优雅解决空指针问题源码级别刨析Optional 1
Java优雅解决空指针问题源码级别刨析Optional
43 0
|
Java
Java优雅解决空指针问题源码级别刨析Optional 2
Java优雅解决空指针问题源码级别刨析Optional
58 0
|
存储 算法 安全
【C++技能树】原来比C方便这么多 --引用、内联函数、Auto、NULL与nullptr
引用必须在声明部分给出定义,不能单单申明.需要指定对象
96 0
|
Java 测试技术 API
开发小技巧系列 - 如何避免NPE,去掉if...else(四)
利用optional来处理各种IF-ELSE的判断
107 0
|
Java 测试技术
开发小技巧系列 - 如何避免NPE,巧用Optional重构三元表达式?(三)
NPE是一个老生长谈的问题,无论新手,还是老手,在开发程序的过程中,都不可避免会遇到,而为了处理NPE,往往需要添加很多重复性的检查代码,又长又臭。NPE系列文章,是总结了过往的开发经验,助力更多新手,避免踩坑。
109 0
|
NoSQL Java API
RedisTemplate 接口误用造成的空指针异常记录(深扒multiGet接口)
RedisTemplate 接口误用造成的空指针异常记录(深扒multiGet接口)
310 0