前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

一篇文章让你弄懂Java8中的Optional是什么?有什么用?

qiguaw 2024-10-28 17:28:49 资源文章 15 ℃ 0 评论

易哥,高级软件架构师、网络工程师、数据库工程师、注册电气工程师。现从事软件架构架构设计工作。

1 概述

Java 8由Oracle公司于2014年3月18日发布,至今已过去数年之久。然而,直到今日仍有许多软件开发者对其相关特性不了解,这可能主要是Java基础教材更新缓慢的原因。为了使大家对与Java8的特性有全面系统的了解,本公众号将连续几篇文章介绍Java8中的各个特性。

Java8中新增的特性主要有:

  • Lambda 表达式 ? Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。
  • 方法引用 ? 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
  • 默认方法 ? 默认方法就是一个在接口里面有了一个实现的方法。
  • 新工具 ? 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
  • Stream API ?新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
  • Date Time API ? 加强对日期与时间的处理。
  • Optional 类 ? Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
  • Nashorn, JavaScript 引擎 ? Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

本文介绍其中的Optional类。其它特性会在后续文章中陆续介绍。

2 Optional类

到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。

Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

常用函数:

  • of:为非null的值创建一个Optional。of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException。因此不经常用。
  • ofNullable:为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
  • isPresent:如果值存在返回true,否则返回false。
  • ifPresent:如果Optional实例有值则为其调用consumer,否则不做处理
  • get:如果Optional有值则将其返回,否则抛出NoSuchElementException。因此也不经常用。
  • orElse:如果有值则将其返回,否则返回指定的其它值。
  • orElseGet:orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值
  • orElseThrow:如果有值则将其返回,否则抛出supplier接口创建的异常。
  • filter:如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。
  • map:如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
  • flatMap:如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。

使用Optional,我们就可以把下面这样的代码进行改写。

public static String getName(User u) {
 if (u == null)
 return "Unknown";
 return u.name;
}

不过,千万不要改写成这副样子。

public static String getName(User u) {
 Optional<User> user = Optional.ofNullable(u);
 if (!user.isPresent())
 return "Unknown";
 return user.get().name;
}

这样改写非但不简洁,而且其操作还是和第一段代码一样。无非就是用isPresent方法来替代u==null。这样的改写并不是Optional正确的用法,我们再来改写一次。

public static String getName(User u) {
 return Optional.ofNullable(u)
 .map(user->user.name)
 .orElse("Unknown");
}

这样才是正确使用Optional的姿势。那么按照这种思路,我们可以安心的进行链式调用,而不是一层层判断了。

使用举例:

public class TestBean {
 public static void main(String[] args) {
 String nullString = null;
 Optional<String> optionalS1 = Optional.ofNullable(nullString);
 String normalString = "HelloWorld";
 Optional<String> optionalS2 = Optional.ofNullable(normalString);

 System.out.println("s1:" + optionalS1.orElse("None value fund!"));
 System.out.println("s2:" + optionalS2.orElse("None value fund!"));
 System.out.println("---");

 System.out.println(
 optionalS1
 .map(a -> {System.out.print("do map... ");return a.concat("+++");})
 .orElse("None value!")
 );
 System.out.println(
 optionalS2
 .map(a -> {System.out.print("do map... ");return a.concat("+++");})
 .orElse("None value!")
 );
 }
}

运行结果:

s1:None value fund!
s2:HelloWorld
---
None value!
has value. HelloWorld+++

3 总结

Java8 提供的Optional类使得Java程序更为健壮,防止代码受到空值的污染。

关于Java8中Optional类的介绍就到这里,至此,通过前面的几篇文章和本文,我们对Java8中的特性进行了较为全面的介绍。希望大家在后续的编码中能使用这些特性,编写更加健壮和易读的代码。


易哥,高级软件架构师、网络工程师、数据库工程师、注册电气工程师。现从事软件架构架构设计工作。

欢迎关注我们,不错过每期的架构师原创干货!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表