Java 8 引入了 Optional
类来简化代码中空指针异常的处理。当代码中调用空对象的方法或属性时,可能会出现空指针异常。考虑到代码中出现空指针异常的可能性非常高,开发者通常会尝试处理每一个可能出现空值的情况,但由于这是一个运行时异常,程序仍然容易出错,并且遗漏空检查的机会仍然很高。
Optional
实例是一个容器对象,用于包含非空对象/值。Optional
对象用于表示空值的存在与否。此类提供各种实用方法,帮助代码处理值为“可用”或“不可用”的情况,而不是检查空值。它在 Java 8 中引入,并且类似于 Guava 中的 Optional
。
Optional
类提供了类型检查解决方案,而不是直接检查空值。此类充当值的包装器。除了处理空值外,Optional
类还提供了许多实用方法,如在空值情况下获取默认值、在底层值为空的情况下抛出异常等。
Optional
类声明
以下是 java.util.Optional<T>
类的声明:
public final class Optional<T> extends Object
Optional
类方法
方法与描述
-
static <T> Optional<T> empty()
返回一个空的 Optional
实例。
-
boolean equals(Object obj)
表明另一个对象是否与此 Optional
“相等”。
-
Optional<T> filter(Predicate<? super <T> predicate>)
如果存在一个值并且该值匹配给定的谓词,则返回一个描述该值的 Optional
,否则返回一个空的 Optional
。
-
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)
如果存在一个值,则应用提供的带有 Optional
的映射函数,并返回该结果,否则返回一个空的 Optional
。
-
T get()
如果此 Optional
中存在值,则返回该值,否则抛出 NoSuchElementException
。
-
int hashCode()
返回存在的值的哈希码值,如果没有值则返回 0。
-
void ifPresent(Consumer<? super T> consumer)
如果存在一个值,则使用该值调用指定的消费者,否则不做任何事情。
-
boolean isPresent()
如果存在一个值则返回 true
,否则返回 false
。
-
<U>Optional<U> map(Function<? super T,? extends U> mapper)
如果存在一个值,则应用提供的映射函数,并如果结果非空,则返回一个描述结果的 Optional
。
-
static <T> Optional<T> of(T value)
返回具有指定非空值的 Optional
。
-
static <T> Optional<T> ofNullable(T value)
返回描述指定值的 Optional
,如果指定的值为 null
则返回一个空的 Optional
。
-
T orElse(T other)
如果存在一个值,则返回该值,否则返回 other
。
-
T orElseGet(Supplier<? extends T> other)
如果存在一个值,则返回该值,否则调用 other
并返回调用的结果。
-
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
如果存在一个值,则返回包含的值,否则根据提供的供应商抛出异常。
-
String toString()
返回此 Optional
的非空字符串表示形式,适用于调试。
-
boolean isEmpty()
如果存在一个值则返回 false
,否则返回 true
。此方法是在 Java 11 中添加到 Optional
API 中的。
此类继承了来自 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<Integer> empty = Optional.empty();
Optional<Integer> a = Optional.ofNullable(value1);
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
实例的值之前使用,因为 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<Integer> empty = Optional.empty();
Optional<Integer> a = Optional.ofNullable(value1);
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
实例,并如果存在值则返回其值,否则调用传递给函数的供应商来生成默认值并返回相同的值。
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) {
Optional<Integer> valueOptional = Optional.ofNullable(null);
Integer value = valueOptional.orElse(Integer.valueOf(-1));
System.out.println(value);
Optional<Integer> valueOptional1 = Optional.ofNullable(Integer.valueOf(10));
Integer value1 = valueOptional1.orElse(Integer.valueOf(-1));
System.out.println(value1);
Optional<Integer> valueOptional2 = Optional.ofNullable(null);
Integer value2 = valueOptional2.orElseGet(() -> (int)(Math.random() * 10));
System.out.println(value2);
Optional<Integer> valueOptional3 = Optional.ofNullable(Integer.valueOf(10));
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();
Integer value = emptyOptional.orElseThrow();
Optional.orElseThrow(Supplier)
方法
我们可以在必要字段未传递的情况下优雅地处理这种情况,使用 orElseThrow(supplier)
方法调用抛出自定义异常。
Optional<Integer> emptyOptional = Optional.empty();
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 {
sum(valueOptional1, valueOptional2);
} catch (Exception e) {
e.printStackTrace();
}
try {
sum(valueOptional2, valueOptional1);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Integer sum(Optional<Integer> value1, Optional<Integer> value2) {
Integer val1 = value1.orElseThrow();
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)