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