误区一 Optional 类型作为字段或参数
分析:
- Optional 不可序列化,如果所在类可序列化就会出问题
- 由于字段和参数可能被赋值为
null
, 实际使用时需要再次判断optional != null
, 造成了二次判断, Optional 本身就是为了清晰表达 "没有值"而设计的
误区二 对数据库输入参数做Optional判断
错误例子:
public User getUserById(String userId) {
return Optional.ofNullable(userId).map(id -> userDao.findById(id)).orElse(null);
}
分析: 对不符合要求的输入应立即拒绝,防止对下层代码造成压力和污染
正确写法:
public User getUserById(String userId) {
// 直接抛出NullPointerException异常
return userDao.findById(Objects.requireNoNull(userId, "userId不能为空");
}
误区三 Optional.map(...) 中再次 null 判断
错误例子:
String productName = Optional.ofNullable(user)
.map(User::getOrder)
.flatMap(order -> Optional.ofNullable(order.getProduct())) // 判断1
.flatMap(product -> Optional.ofNullable(product.getName())) // 判断2
.orElse("");
分析: Optional的map()方法已经对null值进行了处理, 无须二次判断, 请看源代码
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
// public boolean isPresent(){return value != null;}
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
正确写法:
String productName = Optional.ofNullable(user)
.map(User::getOrder)
.map(Order::getProduct)
.map(Product::getName)
.orElse("");
误区四 Optional.ofNullable() 应用于明确非 null 的值
错误例子:
Optional.ofNullable(100);
分析: ofNullable 包含了空判断, 如果明确非空, 就会造成二次判断, 请看源代码
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
正确写法:
Optional.of(100);
网友评论