Java 简明教程

Java - Optional Class

*Optional class*在 Java 8 中引入,用于简化代码中的空指针 exception handling。空指针异常可能发生在代码中调用空对象的 method 或属性的情况下。考虑到代码中空指针异常发生的可能性很高,开发人员通常会尝试针对每种情况处理空值,但由于它仍然是一种运行时异常,因此程序仍然容易出错,并且极有可能漏掉空检查。

Optional 实例是一个容器对象,用于包含非空对象/值。Optional 对象用于用缺失值表示空值。此类具有各种实用方法,用于帮助代码将值处理为“可用”或“不可用”,而不是检查空值。它在 Java 8 中引入,并且类似于 Guava 中的 Optional。

Optional 类提供了类型检查解决方案,而不是直接检查空值。此类充当值的包装器。除了处理空值之外,Optional 类还提供了许多实用方法,例如在空值的情况下获取默认值,在基础值为空的情况下抛出异常。

Optional Class Declaration

以下是 java.util.Optional<T> 类的声明

public final class Optional<T> extends Object

Optional Class Methods

Sr.No.

Method & Description

1

static &lt;T&gt; Optional&lt;T&gt; empty() 返回一个空的 Optional 实例。

2

boolean equals(Object obj) 指示某个其他对象是否“等于”此 Optional。

3

Optional&lt;T&gt; filter(Predicate&lt;? super &lt;T&gt; predicate) 如果值存在并且值与给定的谓词匹配,则返回描述该值的一个 Optional,否则返回一个空 Optional。

4

&lt;U&gt; Optional&lt;U&gt; flatMap(Function&lt;? super T,Optional&lt;U&gt;&gt; mapper) 如果值存在,则将提供的 Optional 承载映射函数应用到该值,返回该结果,否则返回一个空 Optional。

5

T get() 如果在此 Optional 中存在值,则返回该值,否则抛出 NoSuchElementException。

6

int hashCode() 如果存在当前值,返回其哈希代码值,如果不存在任何值,则返回 0(零)。

7

void ifPresent(Consumer&lt;? super T&gt; consumer) 如果存在某个值,使用该值调用指定的使用者,否则不进行任何操作。

8

boolean isPresent() 如果存在某个值,则返回 true;否则,返回 false。

9

&lt;U&gt;Optional&lt;U&gt; map(Function&lt;? super T,? extends U&gt; mapper) 如果存在某个值,则对其应用提供的映射函数,如果结果为非空,则返回描述该结果的 Optional。

10

static &lt;T&gt; Optional&lt;T&gt; of(T value) 返回一个包含指定的非空当前值的 Optional。

11

static &lt;T&gt; Optional&lt;T&gt; ofNullable(T value) 返回描述指定值(如果非空)的 Optional,否则返回一个空的 Optional。

12

T orElse(T other) 如果存在值,则返回该值;否则,返回其他值。

13

T orElseGet(Supplier&lt;? extends T&gt; other) 如果存在值,则返回该值;否则,调用其他值并返回该调用的结果。

14

&lt;X extends Throwable&gt; T orElseThrow(Supplier&lt;? extends X&gt; exceptionSupplier) 返回包含的值(如果存在);否则,抛出由提供的供应商要创建的异常。

15

String toString() 返回此 Optional 的非空字符串表示形式,适合调试。

16

boolean isEmpty() 如果存在某个值,则返回 true;否则,返回 false。

此类从以下类继承方法 −

  1. java.lang.Object

Creating Optional Class Instance

Optional 类提供多种方法来为提供的 value/object 创建 Optional 实例。以下是相应的带有语法的方法及其对应的示例:

Optional.empty() method

此方法返回一个包含空值的 Optional 实例。它可以用来表示一个不存在的值而不是 null。

Optional emptyOptional = Optional.empty();

Optional.of() method

此方法返回一个包含给定非 null 值的 Optional 实例。如果提供的 value 为 null,它将抛出 NullPointerException。

String name = "John";
Optional valueOptional = Optional.of(name);

Optional.ofNullable() method

此方法返回一个带有给定值的可选项实例。如果提供的值为 null,则它会返回一个空的可选项实例。

Optional emptyOptional = Optional.empty();

Example: Creating Optional Instances

以下示例展示了使用上述方法创建可选项对象的情况以及应该使用它们的情况。

package com.tutorialspoint;

import java.util.Optional;

public class OptionalTester {
   public static void main(String[] args) {
      Integer value1 = null;
      Integer value2 = Integer.valueOf(10);

      // Optional.empty - return an empty optional object
      Optional<Integer> empty = Optional.empty();

      //Optional.ofNullable - allows passed parameter to be null.
      Optional<Integer> a = Optional.ofNullable(value1);

      //Optional.of - throws NullPointerException if passed parameter is null
      Optional<Integer> b = Optional.of(value2);

      System.out.println("value of a: " + (a.isPresent() ? a.get(): "0"));
      System.out.println("value of b: " +  (b.isPresent() ? b.get(): "0"));
      System.out.println("value of empty: " +  (empty.isPresent() ? empty.get(): "0"));
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

value of a: 0
value of b: 10
value of empty: 0

Checking Optional Class Instance Value

可选项类提供了以下方法来检查可选项实例是否有值。在使用 get() 方法获取可选项实例值之前,应使用这些方法,因为如果基础值为空,则 get() 方法可能会抛出空指针异常。

Optional.isPresent() method

此方法检查当前的可选项实例,并根据值是否存在返回 true/false。

Optional emptyOptional = Optional.empty();
boolean isValuePresent = emptyOptional.isPresent();

Optional.isEmpty() method

此方法检查当前的可选项实例,并根据值是否存在返回 true/false。此方法已添加到 Java 11 中的可选项 API 中。

Optional emptyOptional = Optional.empty();
boolean isValuePresent = emptyOptional.isEmpty();

Example: Checking Optional Instances

以下示例展示了使用上述方法创建可选项对象的情况以及应该使用它们的情况。

package com.tutorialspoint;

import java.util.Optional;

public class OptionalTester {
   public static void main(String[] args) {
      Integer value1 = null;
      Integer value2 = Integer.valueOf(10);

      // Optional.empty - return an empty optional object
      Optional<Integer> empty = Optional.empty();

      //Optional.ofNullable - allows passed parameter to be null.
      Optional<Integer> a = Optional.ofNullable(value1);

      //Optional.of - throws NullPointerException if passed parameter is null
      Optional<Integer> b = Optional.of(value2);

      System.out.println("value of a: " + (a.isEmpty() ? a.get(): "0"));
      System.out.println("value of b: " +  (b.isPresent() ? b.get(): "0"));
      System.out.println("value of empty: " +  (empty.isPresent() ? empty.get(): "0"));
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

value of a: 0
value of b: 10
value of empty: 0

Using Default Value With Optional Class Methods

可选项类提供了以下方法以从不存在值的可选项实例中获取默认值。

Optional.OrElse() method

此方法会返回检查当前的可选项实例,并返回它的值(如果存在),否则它会返回提供的默认值。

Optional<Integer> valueOptional = Optional.ofNullable(null);
Integer value = valueOptional.orElse(Integer.valueOf(-1));

Optional.OrElseGet(Supplier) method

此方法会返回检查当前的可选项实例,并返回它的值(如果存在),否则它会调用传递给生成默认值并返回它的供给函数。

Optional<Integer> valueOptional = Optional.ofNullable(null);
Integer value = valueOptional.orElseGet(()-> (int)(Math.random() * 10));

Example: Getting Default Values Using Optional Class Methods

以下示例演示了使用上述方法使用可选项对象获取默认值的情况。

package com.tutorialspoint;

import java.util.Optional;

public class OptionalTester {
   public static void main(String[] args) {
      // case 1: Optional is having null as underlying value
      Optional<Integer> valueOptional = Optional.ofNullable(null);
      // orElse will return -1 being default value
      Integer value = valueOptional.orElse(Integer.valueOf(-1));

      System.out.println(value);

      // case 2:  Optional is having not null as underlying value
      Optional<Integer> valueOptional1 = Optional.ofNullable(Integer.valueOf(10));

      //  orElse will return the underlying value
      Integer value1 = valueOptional1.orElse(Integer.valueOf(-1));

      System.out.println(value1);

      // case 3: Optional is having null as underlying value
      Optional<Integer> valueOptional2 = Optional.ofNullable(null);
      // orElse will return a random number between 0 to 10 for default value
      Integer value2 = valueOptional2.orElseGet(()-> (int)(Math.random() * 10));

      System.out.println(value2);

      // case 4:  Optional is having not null as underlying value
      Optional<Integer> valueOptional3 = Optional.ofNullable(Integer.valueOf(10));

      //  orElse will return the underlying value
      Integer value3 = valueOptional3.orElseGet(()-> (int)(Math.random() * 10));

      System.out.println(value3);
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

-1
10
3
10

Optional Class Methods for Throwing Exception

可选项类提供了以下方法以在不存在值时抛出异常。

Optional.OrElseThrow() method

如果未传递必需的字段以优雅地处理该情况,我们可以使用 orElseThrow() 方法调用抛出一个自定义异常。

Optional<Integer> emptyOptional = Optional.empty();
// this call will throw NullPointerException
Integer value = emptyOptional.OrElseThrow();

Optional.OrElseThrow(Supplier) method

如果未传递必需的字段以优雅地处理该情况,我们可以使用 orElseThrow(supplier) 方法调用抛出一个自定义异常。

Optional<Integer> emptyOptional = Optional.empty();
// this call will throw a custom exception as specified by the supplier function
Integer value = emptyOptional.orElseThrow(()-> {throw new RuntimeException("value not present");} );

Example: Throwing Exception Using Optional Class

以下示例演示了在缺少必需参数时使用上述方法抛出并处理异常的情况。

package com.tutorialspoint;

import java.util.Optional;

public class OptionalTester {
   public static void main(String[] args) {
      Optional<Integer> valueOptional1 = Optional.ofNullable(null);
      Optional<Integer> valueOptional2 = Optional.ofNullable(10);

      try {
         // first value being null, NoSuchElementException will occur
         sum(valueOptional1, valueOptional2);
      }catch(Exception e){
         e.printStackTrace();
      }

      try {
         // second value being null, RuntimeException will occur
         sum(valueOptional2, valueOptional1);
      }catch(Exception e){
         e.printStackTrace();
      }
   }

   public static Integer sum(Optional<Integer> value1, Optional<Integer> value2) {
      // throws NoSuchElementException in case underlying value is not present
      Integer val1 = value1.orElseThrow();
      // throws a custom Exception as specified in case underlying value is not present
      Integer val2 = value2.orElseThrow(()-> {throw new RuntimeException("value not present");} );

      return val1 + val2;
   }
}

让我们编译并运行上述程序,这将生成以下结果 −

java.util.NoSuchElementException: No value present
	at java.base/java.util.Optional.orElseThrow(Optional.java:377)
	at com.tutorialspoint.OptionalTester.sum(OptionalTester.java:27)
	at com.tutorialspoint.OptionalTester.main(OptionalTester.java:12)
java.lang.RuntimeException: value not present
	at com.tutorialspoint.OptionalTester.lambda$0(OptionalTester.java:29)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at com.tutorialspoint.OptionalTester.sum(OptionalTester.java:29)
	at com.tutorialspoint.OptionalTester.main(OptionalTester.java:19)