Java8 Optional用法

Optional源码

Optional 的三种构造方式: Optional.of(obj), Optional.ofNullable(obj) 和明确的 Optional.empty()

  • Optional.of(obj): 它要求传入的 obj 不能是 null 值的, 否则还没开始进入角色就倒在了 NullPointerException 异常上了.
  • Optional.ofNullable(obj): 它以一种智能的, 宽容的方式来构造一个 Optional 实例. 来者不拒, 传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).

观点:

  1. 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时, 比如它是一个刚 new 出来的对象(Optional.of(new User(…))), 或者是一个非 null 常量时;
  2. 当想为 obj 断言不为 null 时, 即我们想在万一 obj 为 null 立即报告 NullPointException 异常, 立即修改, 而不是隐藏空指针异常时, 我们就应该果断的用 Optional.of(obj) 来构造 Optional 实例, 而不让任何不可预计的 null 值有可乘之机隐身于 Optional 中.

使用:

  • 存在即返回, 无则提供默认值

    1
    2
    return user.orElse(null);  //而不是 return user.isPresent() ? user.get() : null;
    return user.orElse(UNKNOWN_USER);
  • 存在即返回, 无则由函数来产生

    1
    return user.orElseGet(() -> fetchAUserFromDatabase()); //而不要 return user.isPresent() ? user: fetchAUserFromDatabase();
  • 存在才对它做点什么

    1
    2
    user.ifPresent(System.out::println);
    return user.map(u -> u.getOrders()).orElse(Collections.emptyList())
  • map 是可能无限级联的, 比如再深一层, 获得用户名的大写形式

    1
    2
    3
    return user.map(u -> u.getUsername())
    .map(name -> name.toUpperCase())
    .orElse(null);