前言

看到好多文章都是推荐采用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用的时候记得捕获异常。

Optional乱用Empty之No value present的更多相关文章

  1. Java 8 之 Optional

    Java 8 之 Optional 背景介绍:在我们实际开发中,经常会遇到各种 NullPointerException 报错,为了避免此类问题,需要在业务代码上添加各种if判断,使代码看起来很臃肿, ...

  2. 【原创】JAVA8之妙用Optional解决NPE问题

    引言 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user. ...

  3. Guava源码学习(一)Optional

    基于版本:Guava 22.0 Wiki:Using and avoiding null 0:Optional简介 null在很多场景下会引发问题,NullPointerException困扰过无数的 ...

  4. Java8新特性探索之Optional类

    为什么引入Optional类? 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前 ...

  5. java8 新特性 -Optional的常见用法

    1. Optional 一. 简介 Opitonal是java8引入的一个新类,目的是为了解决空指针异常问题.本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为 ...

  6. Understanding the Router

    Understanding the Router Our module is coming along nicely. However, we're not really doing all that ...

  7. RFC 2616

    Network Working Group R. Fielding Request for Comments: 2616 UC Irvine Obsoletes: 2068 J. Gettys Cat ...

  8. RFC3261--sip

    本文转载自 http://www.ietf.org/rfc/rfc3261.txt 中文翻译可参考 http://wenku.baidu.com/view/3e59517b1711cc7931b716 ...

  9. JAVA的SSH框架登录注册

    Struts 的MVC设计模式可以使我们的逻辑变得很清晰,主要负责表示层的显示. Spring 的IOC和AOP可以使我们的项目在最大限度上解藕. hibernate的就是实体对象的持久化了, 数据库 ...

随机推荐

  1. jQuery EasyUI弹出确认对话框(确认操作中.....)

    因为毕业设计的原因,在初期设计系统的时候没有考虑功能的正确性,所以很多的功能都没有加验证和确认的操作,给人在操作方面上有一些不好的感觉(可能失误点击后,数据就别删除,或者增加了),所以在网上找了一些资 ...

  2. NET .NET深入体验和实战精要

    在学习.NET之前要充分理解基础,在这里将基础的知识点一一列举. 万丈高楼平地起 1.命名空间 命名空间是一种特殊的分类机制,他将与一个特定功能集有关的所有类型都分到一起,是.避免类名冲突的一种方式 ...

  3. [我所理解的REST] 2.REST用来干什么的?

    笔者每当遇到一个新事物的想去了解的时候,总是会问上自己第一个问题,这个新事物是干什么用的?在解释我所理解的REST这个过程中也不例外,这篇博客我们先关注一下REST是干什么用的,然后后续再解释REST ...

  4. Java计算器1.0版

    此版本只是设计了页面,还没有实现事件监听   代码: package com.niit.javagui; import java.awt.Button; import java.awt.FlowLay ...

  5. 团队作业9——测试与发布(Beta版本)(含展示博客)

    团队作业9--测试与发布(Beta版) http://www.cnblogs.com/newteam6/p/6938504.html 团队作业9--展示博客 http://www.cnblogs.co ...

  6. 24点游戏详细截图介绍以及原型、Alpha、Beta对比

    原型设计 图片展示 功能与界面设计 1.登录注册 2.手机号验证 3.24点游戏 4.粉色系女生界面 Alpha 图片展示 功能与界面设计 1.24点游戏 2.背景音乐 3.可查看多种可能的答案 4. ...

  7. 201521123079《java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  8. 201521123075 《Java程序设计》第3周学习总结

    1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...

  9. 201521123115 《Java程序设计》第3周学习总结

    Java 第三周总结 1.本周学习总结 {{uploading-image-747934.png(uploading...)}} 2.书面作业 1.代码阅读 public class Test1 { ...

  10. Struts2-在js中使用struts2标签

    1, 支行是下拉列表,自助银行也是下拉列表,它们是级联关系; <tr> <th width="17%"><span>*</span> ...