这是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()的返回类型为TTg()方法, 通过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()