Java 8 引入了Optional类,该类用于根据值是否存在来操纵数据。 您可以不使用此类而具有相同的功能,但是最终会产生混乱的代码。 换句话说,您的空检查将更少,而NullPointerException则不会。

让我举一个例子,说明为什么不使用Optional会导致问题。
未使用Optional
public class NonOptionalImplementation {public static void main(String[] args) {Animal dog = new Animal(null, 5);String dogModified = dog.getName().toLowerCase();System.out.println(dogModified);}}class Animal {private String name;private int age;Animal(String n, int a) {this.name = n;this.age = a;}public String getName() {return this.name;}public int getAge() {return this.age;}}
您能发现哪里会出问题吗? 显然,当我们到达print语句时,由于对象名称被故意设置为null,它将抛出NullPointerException。
输出
Exception in thread "main" java.lang.NullPointerExceptionat OptionalImplementation.main(OptionalImplementation.java:6)
使用Optional解决了此问题
import java.util.Optional;import java.util.*;public class OptionalImplementation {public static void main(String[] args) {Animal dog = new Animal(null, 5);System.out.println(Optional.ofNullable(dog.getName()).orElse("Name not provided"));}}class Animal {private String name;private int age;Animal(String n, int a) {this.name = n;this.age = a;}public String getName() {return name;}public int getAge() {return this.age;}}
输出
Name not provided
上述实现的简要拆分
- 我们正在创建一个非常简单的类,称为
Animal,我们有 2 个具有构造函数的 getter 方法 - 在我们的主方法中,我们正在创建该
Animal类的实例,但是我们还将第一个参数(恰好是名称)分配给null Optional.ofNullable检查传递的字符串是否为null- 之后,我们尝试打印值
- 我们有这个
.orElse()方法调用,这基本上意味着:如果您要在其上调用该方法的字符串为 null,那么我将使用给出的参数进行打印 - 如果不为空,那么我将打印原始字符串
- 换句话说,如果字符串为
null,它将打印默认值
是不是很酷? 只要看看我们检查空值时代码的外观如何优雅即可。 而且安全!
为了进行比较,让我们尝试不使用Optional类而获得相同的结果。
public class OptionalImplementation {public static void main(String[] args) {Animal dog = new Animal(null, 5);if (dog.getName() == null) {System.out.println("Name not provided");}else {System.out.println(dog.getName().toLowerCase());}}}class Animal {private String name;private int age;Animal(String n, int a) {this.name = n;this.age = a;}public String getName() {return this.name;}public int getAge() {return this.age;}}
输出
Name not provided
它有效..但是干净吗? 我不这么认为!
您也可以使用isPresent()方法检查对象中是否存在值:
import java.util.Optional;public class OptionalImplementation {public static void main(String[] args) {Optional<Object> n = Optional.empty(); // creating an empty stringSystem.out.println(n.isPresent());System.out.println(n);}}
输出
falseOptional.empty
而已。 不是那么难,不是吗? 甚至它都不是很容易理解,但是它也大大简化了您的代码,并且也非常易于阅读和维护。 如果要浏览Optional提供的所有方法,请查看官方 Oracle 文档。
