「Java8系列」NPE神器 Optional

「Java8系列」神秘的Lambda
「Java8系列」神奇的函数式接口
「Java8系列」流式编程Streamjava

Optional类入门

Optional<T> 类(java.util.Optional) 是一个容器类,表明一个值存在或不存在,原来用 null 表示一个值不存在,如今Optional能够更好的表达这个概念。而且能够避免空指针异常。你能够把Optional对象当作一种特殊的集合数据,它至多包含一个元素。编程

经常使用方法:bash

  • Optional.of(T t) : 将指定值用 Optional 封装以后返回,若是该值为 null,则抛出一个 NullPointerException 异常。
  • Optional.empty() : 建立一个空的 Optional 实例。
  • Optional.ofNullable(T t) : 将指定值用 Optional 封装以后返回,若是该值为 null,则返回一个空的 Optional 对象。
  • get() : 若是该值存在,将该值用 Optional 封装返回,不然抛出一个 NoSuchElementException 异常。
  • orElse(T t) : 若是调用对象包含值,返回该值,不然返回t。
  • orElseGet(Supplier s) : 若是调用对象包含值,返回该值,不然返回 s 获取的值。
  • orElseThrow() :它会在对象为空的时候抛出异常。
  • map(Function f) : 若是值存在,就对该值执行提供的 mapping 函数调用。
  • flatMap(Function mapper) : 若是值存在,就对该值执行提供的mapping 函数调用,返回一个 Optional 类型的值,不然就返回一个空的 Optional 对象。

注意:Optional类的设计初衷仅仅是要支持能返回Optional对象的语法,并未考虑做为类的字段使用,也没有实现序列化接口,在领域模型中使用Optional,有可能引起程序故障。app

使用Optional实战

用Optional封装可能为null的值,咱们在项目中不少时候都会遇到,掉一个方法而后返回一个null,最后须要不断的判空。好比获取Map中的不含指定键的值,它的get方法返回的就是一个null。函数

//例如:
 Object value = map.get("key");
 
 //使用Optional封装结果后能够这么写:
 Optional<Object> value = Optional.ofNullable(map.get("key"));
 
 /**
 * 若是想在获取为null之后给个默认值,能够这么写:
 * orElse和orElseGet的区别是当Optional的值是空值时,不管orElse仍是orElseGet都会执行;而当返回的Optional有值时,orElse会执行,而orElseGet不会执行。
 */
 Object value = Optional.ofNullable(map.get("key")).orElse("value");
 Object value1 = Optional.ofNullable(map.get("key")).orElseGet(()->"value");
复制代码

因为某种缘由,函数没法返回某个值,这时除了返回null,Java API比较常见的替代作法是抛出一个异常。这种状况比较典型的例子是使用静态方法Integer.parseInt(String),将String转换为int。在这个例子中,若是String没法解析到对应的整型,该方法就抛出一个NumberFormatException。最后的效果是,发生String没法转换为int时,代码发出一个遭遇非法参数的信号,惟一的不一样是,此次你须要使用try/catch 语句,而不是使用if条件判断来控制一个变量的值是否非空。工具

你也能够用空的Optional对象,对遭遇没法转换的String时返回的非法值进行建模,这时你指望parseInt的返回值是一个optional。咱们没法修改最初的Java方法,可是这无碍咱们进 行须要的改进,你能够实现一个工具方法,将这部分逻辑封装于其中,最终返回一个咱们但愿的 Optional对象,代码以下所示。post

public static Optional<Integer> stringToInt(String s) {
try { 
        //若是String能转换为对应的Integer,将其封装在Optioal对象中返回
        return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
        //不然返回一个空的Optional对象
        return Optional.empty();
    }
}
复制代码

Optional就是讲到这里,这个实在没什么好说的了,你们本身实践吧。ui

你们看后辛苦点个赞点个关注哦!后续还会后更多的博客。有兴趣能够扫码加群。若有错误,烦请指正。 spa

相关文章
相关标签/搜索