ullPointerException 是编码过程当中必需要处理的防护式检查,咱们可能用if(null != user) 或者 Objects.isNull(user)等方式处理,再jdk1.8以后,你能够优雅的处理这个问题app
定义
Optional 类是一个能够为null的容器对象。若是值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它能够保存类型T的值,或者仅仅保存null。Optional提供不少有用的方法,这样咱们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。函数
方法实例演示
例举几个经常使用的函数,而后进行实际使用分析this
of编码
//建立一个值为张三的String类型的Optional
Optional<String> ofOptional = Optional.of("李四");指针
//若是咱们用of方法建立Optional对象时,所传入的值为null,则抛出NullPointerException
Optional<String> nullOptional = Optional.of(null);code
of的用法实际上就是静态工厂方法,示例以下:对象
@Data接口
public class Card { private String name; private String number; private Card() {} private Card(String name,String number) { this.name = name; this.number = number; } public static Card of() { return new Card(); } public static Card of(String name,String number) { return new Card(name,number); } }
目前,静态工厂方法比较流行,若是目标类类不须要子类化,很是推荐使用这种方式。
get开发
若是建立的Optional对象中有值存在则返回此值,若是没有值存在,则会抛出 NoSuchElementException异常
ofNullableget
//为指定的值建立Optional对象,无论所传入的值为null不为null,建立的时候都不会报错
Optional<String> nullOptional = Optional.ofNullable(null); Optional<String> noNullOptional = Optional.ofNullable("李四"); System.out.println(nullOptional.get());//抛出异常 NoSuchElementException: No value present System.out.println(noNullOptional.get());//李四
empty
//建立一个空的String类型的Optional对象 Optional<String> emptyOptional = Optional.empty(); System.out.println(emptyOptional .get());//抛出异常 NoSuchElementException
orElse
存在就返回该值,不存在就返回默认值
Optional<String> stringOptional = Optional.of("张三"); System.out.println(stringOptional.orElse("zhangsan"));//张三 Optional<String> emptyOptional = Optional.empty(); System.out.println(emptyOptional.orElse("李四"));//李四
orElseThrow
若是建立的Optional中有值存在,则返回此值,不然抛出一个由指定的Supplier接口生成的异常
Optional<String> stringOptional = Optional.of("张三"); System.out.println(stringOptional.orElseThrow(Exception::new));
map
若是建立的Optional中的值存在,对该值执行提供的Function函数调用
map方法执行传入的lambda表达式参数对Optional实例的值进行修改,修改后的返回值仍然是一个Optional对象
Optional<String> stringOptional = Optional.of("张三"); System.out.println(stringOptional.map(e -> e.toUpperCase()).orElse("不能为空")); stringOptional = Optional.empty(); System.out.println(stringOptional.map(e -> e.toUpperCase()).orElse("不能为空"));
filter
若是建立的Optional中的值知足filter中的条件,则返回包含该值的Optional对象,不然返回一个空的Optional对象
Optional<String> stringOptional = Optional.of("张三"); System.out.println(stringOptional.filter(e -> e.equals("张三")));//Optional[张三] System.out.println(stringOptional.filter(e -> !e.equals("张三")).orElse("李四"));//张三 stringOptional = Optional.empty(); System.out.println(stringOptional.filter(e -> e.equals("张三")).orElse("李四"));//李四
flagMap
flatMap与map(Funtion)方法相似,区别在于flatMap中的mapper返回
值必须是Optional,map方法的mapping函数返回值能够是任何类型T
Optional<String> stringOptional = Optional.of("张三"); System.out.println(stringOptional.flatMap(e -> Optional.of("李四")).orElse("不能为空"));
可能看到这儿以后并无感受到多么好用,该写的判断仍是要写,我们继续
实际使用
Person p = new Person("李四",11);//若是 p = null 抛出"年龄不能为空"异常 Integer orElseThrow = Optional.ofNullable(p) .map(s -> s.getAge())//返回参数为年龄的function .map(b ->b + 1)//返回参数为年龄+ 1 的function .filter(m -> m.compareTo(10) == 1)//若是年龄大于10则保留,小于10则过滤掉 .orElseThrow(() -> new Exception("年龄不合法"));//若是为空则抛出该异常 System.out.println(orElseThrow);//12
这种用法能够对单条或多条(配合foreach)能简化大量代码和判断,经过抛出统一异常,使用异常拦截器进行拦截,统一处理,能很大程度上提升开发效率和代码阅读性。