Java 简明教程
Java - Optional Class
*Optional class*在 Java 8 中引入,用于简化代码中的空指针 exception handling。空指针异常可能发生在代码中调用空对象的 method 或属性的情况下。考虑到代码中空指针异常发生的可能性很高,开发人员通常会尝试针对每种情况处理空值,但由于它仍然是一种运行时异常,因此程序仍然容易出错,并且极有可能漏掉空检查。
Optional class was introduced in Java 8 to simplify null pointer exception handling in code. A null pointer exception can come in cases where a method or property of a null object is invoked in code. Considering a very high possibility of a null pointer exception in code, developers generally try to handle null for each and every case but still being a runtime exception, programs remain error prone and chances of missing a null check remains high.
Optional 实例是一个容器对象,用于包含非空对象/值。Optional 对象用于用缺失值表示空值。此类具有各种实用方法,用于帮助代码将值处理为“可用”或“不可用”,而不是检查空值。它在 Java 8 中引入,并且类似于 Guava 中的 Optional。
Optional instance is a container object used to contain not-null object/value. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values. It is introduced in Java 8 and is similar to what Optional is in Guava.
Optional 类提供了类型检查解决方案,而不是直接检查空值。此类充当值的包装器。除了处理空值之外,Optional 类还提供了许多实用方法,例如在空值的情况下获取默认值,在基础值为空的情况下抛出异常。
Optional class provides a type check solution instead of directly checking the null value. This class acts as a wrapper over the value. Apart from handling null value, Optional class provides lots of utility methods like getting a default value in case of null value, throwing exception in case underlying value is null.
Optional Class Declaration
以下是 java.util.Optional<T> 类的声明
Following is the declaration for java.util.Optional<T> class −
public final class Optional<T> extends Object
Optional Class Methods
Sr.No. |
Method & Description |
1 |
static <T> Optional<T> empty() Returns an empty Optional instance. |
2 |
boolean equals(Object obj) Indicates whether some other object is "equal to" this Optional. |
3 |
Optional<T> filter(Predicate<? super <T> predicate) If a value is present and the value matches a given predicate, it returns an Optional describing the value, otherwise returns an empty Optional. |
4 |
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper) If a value is present, it applies the provided Optional-bearing mapping function to it, returns that result, otherwise returns an empty Optional. |
5 |
T get() If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException. |
6 |
int hashCode() Returns the hash code value of the present value, if any, or 0 (zero) if no value is present. |
7 |
void ifPresent(Consumer<? super T> consumer) If a value is present, it invokes the specified consumer with the value, otherwise does nothing. |
8 |
boolean isPresent() Returns true if there is a value present, otherwise false. |
9 |
<U>Optional<U> map(Function<? super T,? extends U> mapper) If a value is present, applies the provided mapping function to it, and if the result is non-null, returns an Optional describing the result. |
10 |
static <T> Optional<T> of(T value) Returns an Optional with the specified present non-null value. |
11 |
static <T> Optional<T> ofNullable(T value) Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional. |
12 |
T orElse(T other) Returns the value if present, otherwise returns other. |
13 |
T orElseGet(Supplier<? extends T> other) Returns the value if present, otherwise invokes other and returns the result of that invocation. |
14 |
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) Returns the contained value, if present, otherwise throws an exception to be created by the provided supplier. |
15 |
String toString() Returns a non-empty string representation of this Optional suitable for debugging. |
16 |
boolean isEmpty() Returns true if there is a value present, otherwise false. |
此类从以下类继承方法 −
This class inherits methods from the following class −
-
java.lang.Object
Creating Optional Class Instance
Optional 类提供多种方法来为提供的 value/object 创建 Optional 实例。以下是相应的带有语法的方法及其对应的示例:
Optional class provides multiple methods to create an Optional instance for a provided value/object. Following are the corresponding methods with their syntaxes followed by an example:
Optional.empty() method
此方法返回一个包含空值的 Optional 实例。它可以用来表示一个不存在的值而不是 null。
This method returns an Optional instance with empty value. It can be used to represent an absent value instead of null.
Optional emptyOptional = Optional.empty();
Optional.of() method
此方法返回一个包含给定非 null 值的 Optional 实例。如果提供的 value 为 null,它将抛出 NullPointerException。
This method returns an Optional instance with given not null value. If provided value is null, then it will throw a NullPointerException.
String name = "John";
Optional valueOptional = Optional.of(name);
Optional.ofNullable() method
此方法返回一个带有给定值的可选项实例。如果提供的值为 null,则它会返回一个空的可选项实例。
This method returns an Optional instance with given value. If provided value is null, then it returns an empty Optional Instance.
Optional emptyOptional = Optional.empty();
Example: Creating Optional Instances
以下示例展示了使用上述方法创建可选项对象的情况以及应该使用它们的情况。
Following example showcases the use of above methods to create Optional objects and the cases when we should use them.
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"));
}
}
让我们编译并运行上述程序,这将生成以下结果 −
Let us compile and run the above program, this will produce the following result −
value of a: 0
value of b: 10
value of empty: 0
Checking Optional Class Instance Value
可选项类提供了以下方法来检查可选项实例是否有值。在使用 get() 方法获取可选项实例值之前,应使用这些方法,因为如果基础值为空,则 get() 方法可能会抛出空指针异常。
Optional class provides following method to check if Optional instance has value or not. These methods should be used before using get() method to obtain the value of the Optional instance as get() method can throw null pointer exception in case underlying value is null.
Optional.isPresent() method
此方法检查当前的可选项实例,并根据值是否存在返回 true/false。
This method checks the current optional instance and returns true/false based on value being present or not.
Optional emptyOptional = Optional.empty();
boolean isValuePresent = emptyOptional.isPresent();
Optional.isEmpty() method
此方法检查当前的可选项实例,并根据值是否存在返回 true/false。此方法已添加到 Java 11 中的可选项 API 中。
This method checks the current optional instance and returns true/false based on value being present or not. This method was added to Optional API in Java 11.
Optional emptyOptional = Optional.empty();
boolean isValuePresent = emptyOptional.isEmpty();
Example: Checking Optional Instances
以下示例展示了使用上述方法创建可选项对象的情况以及应该使用它们的情况。
Following example showcases the use of above methods to create Optional objects and the cases when we should use them.
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"));
}
}
让我们编译并运行上述程序,这将生成以下结果 −
Let us compile and run the above program, this will produce the following result −
value of a: 0
value of b: 10
value of empty: 0
Using Default Value With Optional Class Methods
可选项类提供了以下方法以从不存在值的可选项实例中获取默认值。
Optional class provides following methods to get a default value from an Optional instance if value is not present.
Optional.OrElse() method
此方法会返回检查当前的可选项实例,并返回它的值(如果存在),否则它会返回提供的默认值。
This method returns checks the current optional instance and returns its value if present otherwise it returns the provided default value.
Optional<Integer> valueOptional = Optional.ofNullable(null);
Integer value = valueOptional.orElse(Integer.valueOf(-1));
Optional.OrElseGet(Supplier) method
此方法会返回检查当前的可选项实例,并返回它的值(如果存在),否则它会调用传递给生成默认值并返回它的供给函数。
This method returns checks the current optional instance and returns its value if present otherwise it invokes the supplier function passed to the generate the default value and return the same.
Optional<Integer> valueOptional = Optional.ofNullable(null);
Integer value = valueOptional.orElseGet(()-> (int)(Math.random() * 10));
Example: Getting Default Values Using Optional Class Methods
以下示例演示了使用上述方法使用可选项对象获取默认值的情况。
Following example showcases the use of above methods to get default value using Optional objects.
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);
}
}
让我们编译并运行上述程序,这将生成以下结果 −
Let us compile and run the above program, this will produce the following result −
-1
10
3
10
Optional Class Methods for Throwing Exception
可选项类提供了以下方法以在不存在值时抛出异常。
Optional class provides following methods to throw exception in case value is not present.
Optional.OrElseThrow() method
如果未传递必需的字段以优雅地处理该情况,我们可以使用 orElseThrow() 方法调用抛出一个自定义异常。
We can throw a custom exception in case a required field is not passed to handle the case gracefully using orElseThrow() method call.
Optional<Integer> emptyOptional = Optional.empty();
// this call will throw NullPointerException
Integer value = emptyOptional.OrElseThrow();
Optional.OrElseThrow(Supplier) method
如果未传递必需的字段以优雅地处理该情况,我们可以使用 orElseThrow(supplier) 方法调用抛出一个自定义异常。
We can throw a custom exception in case a required field is not passed to handle the case gracefully using orElseThrow(supplier) method call.
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
以下示例演示了在缺少必需参数时使用上述方法抛出并处理异常的情况。
Following example showcases the use of above methods to throw and handle exception in case of required paramters are missing.
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;
}
}
让我们编译并运行上述程序,这将生成以下结果 −
Let us compile and run the above program, this will produce the following result −
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)