看到好多文章都是推荐采用Optinal的,而经常我遇到问题的时候就想:如果设计成optional的话就不会忽略这种NullPointException错误了。然而,optional并不是想用就随便用的。今天花了10分钟追踪一个bug,根源就是optional滥用。
API返回失败,没有描述原因。看着蛋疼,因为公开的API不方便返回错误详情。于是查log,发现错误日志的message为:<code>No value present</code>。没搞清楚这个错误信息是哪一层跑出来的。需要进一步跟踪。<code>A=>B=>C=>D</code>,一直追踪到C层才找到问题。
问题代码如下:
这是一个创建工厂类,负责创建一个可以使用对象。所有的字段都采用了Opetional的包裹。这个是对象,理应不包含业务逻辑,应该没有错误异常。如果有异常应该显式的<code>throws</code>出来,不然这个非检查性异常将在出现bug的时候难以定位。而这里确实有一个异常没有捕获,而且也不能保证不会发生,甚至就是这里引起的bug:<code>java.util.Optional#get</code>
源码如下:
虽然没有显式的抛出异常,但在javadoc中写清楚了会出现的问题。而我们这些新手则没有认真看文档就想当然的采用了。以为当内容为<code>null</code>的时候get出来的还是<code>null</code>。
Find Uage找这个Builder的用法发现:
这里直接使用了<code>Optional.OfNullable</code>。然而,我们知道在下一步中会调用get,get的时候回判断是否是<code>null</code>,<code>null</code>会抛出异常。这简直就是自己挖坑,写一个条件抛异常,而传参数又专门去符合这个条件。前面也没有校验,外面也没有捕获异常,最终导致异常直接一路抛出到API外层去了。
Optional不要滥用,Optional不是安全的随便用的,Optional用的时候记得捕获异常。
本文转自Ryan.Miao博客园博客,原文链接:http://www.cnblogs.com/woshimrf/p/java8-optinal-exception.html,如需转载请自行联系原作者