Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络编程

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类引用

Java 有用资源

Java - Optional 类



Optional 类是在 Java 8 中引入的,用于简化代码中的空指针异常处理。当代码中调用空对象的方法或属性时,可能会出现空指针异常。考虑到代码中空指针异常的可能性非常高,开发人员通常会尝试针对每种情况处理空值,但它仍然是一个运行时异常,程序仍然容易出错,并且遗漏空值检查的可能性仍然很高。

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

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

Optional 类声明

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

public final class Optional<T> extends Object

Optional 类方法

序号 方法和描述
1

static <T> Optional<T> empty()

返回一个空的 Optional 实例。

2

boolean equals(Object obj)

指示其他某个对象是否“等于”此 Optional。

3

Optional<T> filter(Predicate<? super <T> predicate)

如果存在值并且该值与给定的谓词匹配,则返回一个描述该值的 Optional,否则返回一个空的 Optional。

4

<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)

如果存在值,则将提供的 Optional 映射函数应用于它,返回该结果,否则返回一个空的 Optional。

5

T get()

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

6

int hashCode()

返回现有值的哈希码值(如果有),或者如果不存在值则返回 0(零)。

7

void ifPresent(Consumer<? super T> consumer)

如果存在值,则使用该值调用指定的使用者,否则不执行任何操作。

8

boolean isPresent()

如果存在值,则返回 true,否则返回 false。

9

<U>Optional<U> map(Function<? super T,? extends U> mapper)

如果存在值,则将提供的映射函数应用于它,如果结果非空,则返回一个描述结果的 Optional。

10

static <T> Optional<T> of(T value)

返回一个包含指定存在的非空值的 Optional。

11

static <T> Optional<T> ofNullable(T value)

返回一个描述指定值的 Optional(如果非空),否则返回一个空的 Optional。

12

T orElse(T other)

如果存在值,则返回值,否则返回 other。

13

T orElseGet(Supplier<? extends T> other)

如果存在值,则返回值,否则调用 other 并返回该调用的结果。

14

<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

返回包含的值(如果存在),否则抛出由提供的提供程序创建的异常。

15

String toString()

返回此 Optional 的非空字符串表示形式,适用于调试。

16

boolean isEmpty()

如果存在值,则返回 true,否则返回 false。

此类继承自以下类:

  • java.lang.Object

创建 Optional 类实例

Optional 类提供多种方法来为提供的值/对象创建 Optional 实例。以下是对应的方法及其语法,后跟一个示例

Optional.empty() 方法

此方法返回一个值为空的 Optional 实例。它可以用来表示缺失的值,而不是 null。

Optional emptyOptional = Optional.empty();

Optional.of() 方法

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

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

Optional.ofNullable() 方法

此方法返回一个包含给定值的 Optional 实例。如果提供的值为 null,则返回一个空的 Optional 实例。

Optional emptyOptional = Optional.empty();

示例:创建 Optional 实例

以下示例展示了如何使用上述方法创建 Optional 对象以及何时应该使用它们。

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

检查 Optional 类实例的值

Optional 类提供以下方法来检查 Optional 实例是否包含值。在使用 get() 方法获取 Optional 实例的值之前,应该使用这些方法,因为如果底层值为 null,get() 方法可能会抛出空指针异常。

Optional.isPresent() 方法

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

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

Optional.isEmpty() 方法

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

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

示例:检查 Optional 实例

以下示例展示了如何使用上述方法创建 Optional 对象以及何时应该使用它们。

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

使用 Optional 类方法获取默认值

Optional 类提供以下方法,如果 Optional 实例的值不存在,则获取默认值。

Optional.orElse() 方法

此方法检查当前的 Optional 实例,如果存在则返回其值,否则返回提供的默认值。

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

Optional.orElseGet(Supplier) 方法

此方法检查当前的 Optional 实例,如果存在则返回其值,否则调用传递给它的 Supplier 函数生成默认值并返回。

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

示例:使用 Optional 类方法获取默认值

以下示例展示了如何使用上述方法使用 Optional 对象获取默认值。

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 类用于抛出异常的方法

Optional 类提供以下方法,如果值不存在则抛出异常。

Optional.orElseThrow() 方法

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

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

Optional.orElseThrow(Supplier) 方法

如果未传递必需字段,我们可以抛出一个自定义异常,以便使用 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");} );

示例:使用 Optional 类抛出异常

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

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)
广告