这是Java SE 8 for the Really Impatient的一篇笔记。
一个Optional对象要么有内容(contain a non-null value),要么其内容为空。 Optional如果使用不当并不能体现它的优势。比如,
// 下面两段代码都可能抛异常
Optional<T> optionalValue = ...;
optionalValue.get().someMethod();
T value = ...;
value.someMethod();
// 下面两段代码都有繁琐的if判断
if (optionalValue.isPresent())
optionalValue.get().someMethod();
if (value != null)
value.someMethod();
Optional定义了一些方法,这些方法可以在一个Optional对象有内容时才执行某段代码, 或者没有内容时提供替代性的值。 使用这些方法,才能让Optional发挥优势,使代码远离NullPointerException或者繁琐的null值判断。
// 如果Optional对象里有非null值,则执行某个操作;否则什么也不做
optionalValue.ifPresent(v -> results.add(v));
// 如果Optional对象里有非null值,那么把这个值赋给result;否者把"foo"赋给result
String result = optionalString.orElse("foo");
String result = optionalString.orElseGet(() -> SOME_MAP.get("key"));
String result = optionalString.orElseThrow(NoSuchElementException::new);
Optional对象可以通过下面的方法创建,
Optional.empty(); // 内容为空
Optional.of(obj); // 如果obj为null会抛异常
Optional.ofNullable(obj); // 如果obj不为null,返回Optional.of(obj),否则返回Optional.empty()
可以用flatMap
方法来chaining。
假设obj.f()
的返回类型为T
,T
有g()
方法,
通过obj.f().g()
可以“连续”调用(chaining。当然如果obj.f()
返回null则发生NPE/NullPointerException)。
假设有obj.f_opt()
返回Optional<T>
类型,那么可以通过obj.f_opt().flatMap(T::g)
实现“连续”调用。
如果obj.f_opt()
的返回值没有内容,那么obj.f_opt().flatMap(T::g)
的返回值就是Optional.empty()
,不会抛出NPE。
flatMap
可以一直“串”下去,obj.f_opt().flatMap(T::g).flatMap(U::h)...
;
只要中间任何一次flatMap
调用返回Optional.empty()
,最终返回值就是Optional.empty()
。