1. Optional介绍
Optional是Java8提供的一个容器对象,可以包含一个为null
或者不为null
的对象;使用该对象可以更方便的避免项目中的NPE,在新版的Spring Data JPA中已经实现了对该类的支持;
注意该类是被final修饰的,同时没有实现任何接口;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
// ......
}
2. Optional的创建方式
Optional类中有两个私有的构造方法Optional()
和Optional(T value)
,同时提供了empty()
、of(T value)
和ofNullable(T value)
三个公有的静态方法用于创建Optional对象;
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
/**
* 私有的无参构造方法
*/
private Optional() {
this.value = null;
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
/**
* 私有的有参构造方法
*/
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
}
三个公共的创建Optional对象静态方法介绍:
- empty():创建一个包含null对象的Optional对象;
- of(T value):创建一个包含value对象的Optional对象,若value为null则抛出NullPointerException;
- ofNullable(T value):创建一个包含value对象的Optional对象,若value为null则返回包含null对象的Optional对象;
public class OptionalTest {
public static void main(String[] args) {
Optional<Object> optional1 = Optional.empty();
System.out.println("optional1: " + optional1);
try {
Optional<String> optional2 = Optional.of(null);
} catch (Exception e) {
System.out.println("optional2: " + e);
}
Optional<String> optional3 = Optional.of("hello optional");
System.out.println("optional3: " + optional3);
Optional<String> optional4 = Optional.ofNullable(null);
System.out.println("optional4: " + optional4);
Optional<String> optional5 = Optional.ofNullable("hello optional");
System.out.println("optional5: " + optional5);
}
}
// 运行结果
optional1: Optional.empty
optional2: java.lang.NullPointerException
optional3: Optional[hello optional]
optional4: Optional.empty
optional5: Optional[hello optional]
3. Optional的API介绍
-
get():获取Optional对象中的值,若值为null则抛出NoSuchElementException异常;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); System.out.println("optional1: " + optional1.get()); Optional<String> optional2 = Optional.ofNullable(null); System.out.println("optional2: " + optional2.get()); } }
// 运行结果 optional1: hello optional Exception in thread "main" java.util.NoSuchElementException: No value present at java.util.Optional.get(Optional.java:135) at cn.jackiegu.java8.study.optional.OptionalTest.main(OptionalTest.java:17)
-
isPresent():判断Optional对象中的值是否不为null;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); System.out.println("optional1: " + optional1.isPresent()); Optional<String> optional2 = Optional.ofNullable(null); System.out.println("optional2: " + optional2.isPresent()); } }
// 运行结果 optional1: true optional2: false
-
ifPresent(Consumer<? super T> consumer):如果Optional对象中的值不为null,则将该值作为消费者接口的参数进行消费;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); optional1.ifPresent(System.out::println); Optional<String> optional2 = Optional.ofNullable(null); optional2.ifPresent(System.out::println); } }
// 运行结果 hello optional
-
filter(Predicate<? super T> predicate):如果Optional对象中的值不为null,则将该值作为断言接口的参数进行断言,断言成功时返回当前Optional对象,否则返回一个包含null值得Optional对象;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); Optional<String> optional2 = optional1.filter(item -> item.contains("hello")); System.out.println("optional1.equals(optional2): " + optional1.equals(optional2)); System.out.println("optional2: " + optional2); Optional<String> optional3 = optional1.filter(item -> item.contains("hi")); System.out.println("optional1.equals(optional3): " + optional1.equals(optional3)); System.out.println("optional3: " + optional3); } }
// 运行结果 optional1.equals(optional2): true optional2: Optional[hello optional] optional1.equals(optional3): false optional3: Optional.empty
-
map(Function<? super T, ? extends U> mapper):如果Optional对象中的值不为null,则将该值作为映射接口的参数进行映射,返回一个新的Optional对象;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); Optional<String[]> optional2 = optional1.map(item -> item.split("")); System.out.println("optional2: " + Arrays.toString(optional2.get())); } }
// 运行结果 optional2: [h, e, l, l, o, , o, p, t, i, o, n, a, l]
-
flatMap(Function<? super T, Optional> mapper):该方法与
map
方法基本一致; -
orElse(T other):如果Optional对象中的值不为null,则返回该值,否则返回other;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); System.out.println("optional1: " + optional1.orElse("hi optional")); Optional<String> optional2 = Optional.ofNullable(null); System.out.println("optional2: " + optional2.orElse("hi optional")); } }
// 运行结果 optional1: hello optional optional2: hi optional
-
orElseGet(Supplier<? extends T> other):如果Optional对象中的值不为null,则返回该值,否则返回生产者接口返回的值;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); System.out.println("optional1: " + optional1.orElseGet(() -> { System.out.println("optional1 supplier running"); return "hi optional"; })); Optional<String> optional2 = Optional.ofNullable(null); System.out.println("optional2: " + optional2.orElseGet(() -> { System.out.println("optional2 supplier running"); return "hi optional"; })); } }
// 运行结果 optional1: hello optional optional2 supplier running optional2: hi optional
-
orElseThrow(Supplier<? extends X> exceptionSupplier):如果Optional对象中的值不为null,则返回该值,否则抛出异常生产者返回的异常;
public class OptionalTest { public static void main(String[] args) { Optional<String> optional1 = Optional.ofNullable("hello optional"); System.out.println("optional1: " + optional1.orElseThrow(() -> new RuntimeException("optional1 runtimeException"))); Optional<String> optional2 = Optional.ofNullable(null); System.out.println("optional2: " + optional2.orElseThrow(() -> new RuntimeException("optional2 runtimeException"))); } }
// 运行结果 optional1: hello optional Exception in thread "main" java.lang.RuntimeException: optional2 runtimeException at cn.jackiegu.java8.study.optional.OptionalTest.lambda$main$1(OptionalTest.java:18) at java.util.Optional.orElseThrow(Optional.java:290) at cn.jackiegu.java8.study.optional.OptionalTest.main(OptionalTest.java:18)