原文: https://javatutorial.net/java-optional-example

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

Java `Optional`示例 - 图1

让我举一个例子,说明为什么不使用Optional会导致问题。

未使用Optional

  1. public class NonOptionalImplementation {
  2. public static void main(String[] args) {
  3. Animal dog = new Animal(null, 5);
  4. String dogModified = dog.getName().toLowerCase();
  5. System.out.println(dogModified);
  6. }
  7. }
  8. class Animal {
  9. private String name;
  10. private int age;
  11. Animal(String n, int a) {
  12. this.name = n;
  13. this.age = a;
  14. }
  15. public String getName() {
  16. return this.name;
  17. }
  18. public int getAge() {
  19. return this.age;
  20. }
  21. }

您能发现哪里会出问题吗? 显然,当我们到达print语句时,由于对象名称被故意设置为null,它将抛出NullPointerException

输出

  1. Exception in thread "main" java.lang.NullPointerException
  2. at OptionalImplementation.main(OptionalImplementation.java:6)

使用Optional解决了此问题

  1. import java.util.Optional;
  2. import java.util.*;
  3. public class OptionalImplementation {
  4. public static void main(String[] args) {
  5. Animal dog = new Animal(null, 5);
  6. System.out.println(Optional.ofNullable(dog.getName()).orElse("Name not provided"));
  7. }
  8. }
  9. class Animal {
  10. private String name;
  11. private int age;
  12. Animal(String n, int a) {
  13. this.name = n;
  14. this.age = a;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public int getAge() {
  20. return this.age;
  21. }
  22. }

输出

  1. Name not provided

上述实现的简要拆分

  • 我们正在创建一个非常简单的类,称为Animal,我们有 2 个具有构造函数的 getter 方法
  • 在我们的主方法中,我们正在创建该Animal类的实例,但是我们还将第一个参数(恰好是名称)分配给null
  • Optional.ofNullable检查传递的字符串是否为null
  • 之后,我们尝试打印值
  • 我们有这个.orElse()方法调用,这基本上意味着:如果您要在其上调用该方法的字符串为 null,那么我将使用给出的参数进行打印
  • 如果不为空,那么我将打印原始字符串
  • 换句话说,如果字符串为null,它将打印默认值

是不是很酷? 只要看看我们检查空值时代码的外观如何优雅即可。 而且安全!

为了进行比较,让我们尝试不使用Optional类而获得相同的结果。

  1. public class OptionalImplementation {
  2. public static void main(String[] args) {
  3. Animal dog = new Animal(null, 5);
  4. if (dog.getName() == null) {
  5. System.out.println("Name not provided");
  6. }
  7. else {
  8. System.out.println(dog.getName().toLowerCase());
  9. }
  10. }
  11. }
  12. class Animal {
  13. private String name;
  14. private int age;
  15. Animal(String n, int a) {
  16. this.name = n;
  17. this.age = a;
  18. }
  19. public String getName() {
  20. return this.name;
  21. }
  22. public int getAge() {
  23. return this.age;
  24. }
  25. }

输出

  1. Name not provided

它有效..但是干净吗? 我不这么认为!

您也可以使用isPresent()方法检查对象中是否存在值:

  1. import java.util.Optional;
  2. public class OptionalImplementation {
  3. public static void main(String[] args) {
  4. Optional<Object> n = Optional.empty(); // creating an empty string
  5. System.out.println(n.isPresent());
  6. System.out.println(n);
  7. }
  8. }

输出

  1. false
  2. Optional.empty

而已。 不是那么难,不是吗? 甚至它都不是很容易理解,但是它也大大简化了您的代码,并且也非常易于阅读和维护。 如果要浏览Optional提供的所有方法,请查看官方 Oracle 文档