java1.8之Optional

546 阅读2分钟

简介

java 1.8引入java.util.Optional类可以更优雅的替代空值判断,减少代码中的空指针异常。可以当作一个特殊的集合数据,至多包含一个元素。Optional可以是包含T类型对象或者空的Optional对象,设计初衷仅仅是支持能返回Optional对象的语法,所以引入该语法并非是完全消除null引用。

类的方法

方法 描述
empty 返回空的Optional实例
of 创建Optional,参数不能为null
ofNullable 创建Optional,参数可以为null
get 存在值,Optional封装返回,不存在,会抛出NoSuchElementException异常
isPresent 判断值是否存在
ifPresent 值存在,执行该值方法调用,否则不调用
filter 判断是否满足Predicate,满足返回该值的Optional对象,否则返回空的Optional对象
map 值存在,执行提供的函数调用
flatMap 与map功能相似,区别是map可以返回任何类型的返回值T,flatMap只能返回Optional类型
orElse 值存在返回该值,不存在返回默认值,不管Optional有没有值都会调用
orElseGet orElse方法的延迟调用版,只有在Optional对象不含值的时候才会调用
orElseThrow 值不存在抛出定制类型异常

Optional的使用

1.空值的判断

如下代码获取程序名方法使用Optional替换null引用判断:

public static String getProgramName(Program p){
    Optional<Program> program = Optional.ofNullable(p);
    if(!program.isPresent()){
        return "UnKnow";
    }
    return p.getName();
}

获取程序名的时候,利用isPresent()方法判断是否存在来替代null引用空判断,并未更简洁,不建议这样写,我们进一步使用Optional进行改写,代码如下:

public static String getProgramName(Program p){
    return Optional.ofNullable(p)
            .map(item-> item.getName())
            .orElse("UnKnow");
}

2.过滤值和链式调用

如果我们想查询某一产品(idea产品)的程序名,如下代码:

public static String getProgramName(Product product){
    return Optional.ofNullable(product)
            .filter(item->item.getName().equals("idea"))
            .map(Product::getProject)
            .map(Project::getProgram)
            .map(Program::getName).orElse("unKnow");

}

利用Optional进行处理会变的很清晰,可读性更强。如果进行null引用的判断,会嵌套很多的if条件语句或者每次判空进行返回,都会显得有些复杂,不利于后期维护。 当然还有其它场景可以进行null引用优化,另外需要注意的是Optional并未实现Serializable接口,因此不能作为类的字段,否则在使用有序列化要求的库或者框架会出现问题。

总结

1.使用Optional会有助于我们设计更好的API,有效的防止代码中出现的空指针异常。

2.我们在使用的时候要注意Optional目的只是能返回Optional对象的语法

参考书籍:《java8实战》