一个项目中必不可少的代码可能长这样:
Order order = orderCourseMapper.selectByPrimaryKey(vo.getOrderId()); if(order == null) throw new OrderException(ErrorCode.ERROR_NOCOURSEORDER); if(order.getStatus() != null && order.getStatus() !=DBConstant.OrderStatus.ALREADY) throw new OrderException(ErrorCode.ERROR_NOTCOMPLETEORDER);可以看到,对于Order属性status我做了两个if判断,就是为了防止NullPointerException,在有些业务场景下,甚至还需要更多的if判空,这就是我们常说的“判空炸弹”,这样会使我们的代码很不优雅,可读性很差!
上面的代码用Optional可以这么写:
Order order = orderCourseMapper.selectByPrimaryKey(vo.getOrderId()); if(Optional.ofNullable(order) .map(m -> m.getStatus()) .orElseThrow(() -> new OrderException(ErrorCode.ERROR_ARG)) !=DBConstant.OrderStatus.ALREADY) throw new OrderException(ErrorCode.ERROR_NOTCOMPLETEORDER);好像代码没有简洁多少,但是代码更优雅了不是吗?好吧,我承认我就喜欢这样另类的风格!!!
下面介绍下Optional:
它的部分源码长这样:
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.ofNullable(T)--创建允许包装对象值为null的Optional对象
常用的方法有:
1>Optional.ofNullable(order).ifPresent(o ->System.out.println(“消费函数”))
只有当order不为null时才会执行消费函数
2>Optional.ofNullable(order).map(o -> o.getCode()).orElse("未找到"))
order为null返回“未找到”,否则返回order.getCode();
3>Optional.ofNullable(order).map(o -> o.getCode()).orElseGet(() ->System.out.println(“未找到”)))
4>Optional.ofNullable(order).map(o -> o.getCode()).orElseThrow(() -> new OrderException(ErrorCode.ERROR_ARG)))
orElseThrow()方法适用于包装对象值为空时需要抛出特定异常的场景
像这样:
Optional.ofNullable(new Person())
.map(x->x.country)
.map(x->x.provinec)
.map(x->x.city)
.map(x->x.name)
.orElse("unkonwn");
这里用Optional作为每一次返回的外壳,如果有某个位置返回了null,则会直接得到"unkonwn"。
对于单个值的判断,其实没有体现太多优势!