Optional乱用Empty之No value present

简介:

前言

看到好多文章都是推荐采用Optinal的,而经常我遇到问题的时候就想:如果设计成optional的话就不会忽略这种NullPointException错误了。然而,optional并不是想用就随便用的。今天花了10分钟追踪一个bug,根源就是optional滥用。

问题描述

API返回失败,没有描述原因。看着蛋疼,因为公开的API不方便返回错误详情。于是查log,发现错误日志的message为:No value present。没搞清楚这个错误信息是哪一层跑出来的。需要进一步跟踪。A=>B=>C=>D,一直追踪到C层才找到问题。

问题代码如下:

public FieldBuilder withSubcategoryId(Optional<String> id) {
    this.id = id.get();
    return this;
}

这是一个创建工厂类,负责创建一个可以使用对象。所有的字段都采用了Opetional的包裹。这个是对象,理应不包含业务逻辑,应该没有错误异常。如果有异常应该显式的throws出来,不然这个非检查性异常将在出现bug的时候难以定位。而这里确实有一个异常没有捕获,而且也不能保证不会发生,甚至就是这里引起的bug:java.util.Optional#get

源码如下:

/**
 * If a value is present in this {@code Optional}, returns the value,
 * otherwise throws {@code NoSuchElementException}.
 *
 * @return the non-null value held by this {@code Optional}
 * @throws NoSuchElementException if there is no value present
 *
 * @see Optional#isPresent()
 */
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

虽然没有显式的抛出异常,但在javadoc中写清楚了会出现的问题。而我们这些新手则没有认真看文档就想当然的采用了。以为当内容为null的时候get出来的还是null

Find Uage找这个Builder的用法发现:

new FieldBuilder().withSubcategoryId(Optional.ofNullable(entity.getSubcategoryId()))

这里直接使用了Optional.OfNullable。然而,我们知道在下一步中会调用get,get的时候回判断是否是nullnull会抛出异常。这简直就是自己挖坑,写一个条件抛异常,而传参数又专门去符合这个条件。前面也没有校验,外面也没有捕获异常,最终导致异常直接一路抛出到API外层去了。

结论

Optional不要滥用,Optional不是安全的随便用的,Optional用的时候记得捕获异常。



本文转自Ryan.Miao博客园博客,原文链接:http://www.cnblogs.com/woshimrf/p/java8-optinal-exception.html,如需转载请自行联系原作者

相关文章
|
5月前
|
Linux 开发工具 Android开发
[√]leak tracer的stack address始终无法被addr2line识别
[√]leak tracer的stack address始终无法被addr2line识别
55 0
|
4月前
|
数据采集
运行爬虫时报错AttributeError—— 'str' object has no attribute 'capabilities'
运行爬虫时报错AttributeError—— 'str' object has no attribute 'capabilities'
243 0
|
5月前
Optional没有peek函数?自己写一个
Optional没有peek函数?自己写一个
38 0
|
5月前
|
JSON 小程序 API
小程序踩坑-Setting data field "list" to undefined is invalid.
小程序踩坑-Setting data field "list" to undefined is invalid.
127 0
|
8月前
|
JavaScript
vue 渲染列表报错Avoid using non-primitive value as key, use string/number value instead. found in
vue 渲染列表报错Avoid using non-primitive value as key, use string/number value instead. found in
40 0
|
9月前
|
存储 SQL API
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
|
11月前
Multiple substitutions specified in non-positional format; did you mean to add BUG(7)
Multiple substitutions specified in non-positional format; did you mean to add BUG(7)
Optional int parameter ‘id‘ is present but cannot be translated into a null value due to being ……
Optional int parameter ‘id‘ is present but cannot be translated into a null value due to being ……
164 0
|
JSON 数据格式
遇到【Unexpected character (‘“‘ (code 34)): was expecting comma to separate Object entries】的解决办法
遇到【Unexpected character (‘“‘ (code 34)): was expecting comma to separate Object entries】的解决办法
遇到【Unexpected character (‘“‘ (code 34)): was expecting comma to separate Object entries】的解决办法
解决办法:Type safety: The expression of type List needs unchecked conversion to conform
解决办法:Type safety: The expression of type List needs unchecked conversion to conform
181 0