JAVA Optional
Optional
空指针异常一直是困扰Java程序员的问题,也是我们必须要考虑的。当业务代码中充满了if else判断null 的时候程序变得不再优雅,在Java8中提供了Optional类为我们解决NullPointerException。
我们先来看看这段代码有什么问题?
classUser {
String name;
publicString getName() {
returnname;
}
}
publicstatic String getUserName(User user){
returnuser.getName();
}
这段代码看起来很正常,每个User都会有一个名字。所以调用getUserName方法会发生什么呢? 实际这是不健壮的程序代码,当User对象为null的时候会抛出一个空指针异常。
我们普遍的做法是通过判断user != null然后获取名称
publicstatic String getUserName(User user){
if(user != null){
returnuser.getName();
}
returnnull;
}
但是如果对象嵌套的层次比较深的时候这样的判断我们需要编写多少次呢?难以想象
处理空指针
使用Optional优化代码
publicstatic String getUserNameByOptional(User user) {
Optional<String> userName = Optional.ofNullable(user).map(User::getName);
returnuserName.orElse(null);
}
当user为null的时候我们设置UserName的值为null,否则返回getName的返回值,但此时不会抛出空指针。
在之前的代码片段中是我们最熟悉的命令式编程思维,写下的代码可以描述程序的执行逻辑,得到什么样的结果。 后面的这种方式是函数式思维方式,在函数式的思维方式里,结果比过程更重要,不需要关注执行的细节。程序的具体执行由编译器来决定。 这种情况下提高程序的性能是一个不容易的事情。
我们再次了解下Optional中的一些使用方法
Optional方法
创建 Optional 对象
你可以通过静态工厂方法Optional.empty,创建一个空的Optional对象:
Optional<User> emptyUser = Optional.empty();
创建一个非空值的Optional
Optional<User> userOptional = Optional.of(user);
如果user是一个null,这段代码会立即抛出一个NullPointerException,而不是等到你试图访问user的属性值时才返回一个错误。
可接受null的Optional
Optional<User> ofNullOptional = Optional.ofNullable(user);
使用静态工厂方法Optional.ofNullable,你可以创建一个允许null值的Optional对象。
如果user是null,那么得到的Optional对象就是个空对象,但不会让你导致空指针。
使用map从Optional对象中提取和转换值
Optional<User> ofNullOptional = Optional.ofNullable(user);
Optional<String> userName = ofNullOptional.map(User::getName);
这种操作就像我们之前在操作Stream是一样的,获取的只是User中的一个属性。
默认行为及解引用Optional对象
我们决定采用orElse方法读取这个变量的值,使用这种方式你还可以定义一个默认值, 遭遇空的Optional变量时,默认值会作为该方法的调用返回值。 Optional类提供了多种方法读取 Optional实例中的变量值。
get()是这些方法中最简单但又最不安全的方法。如果变量存在,它直接返回封装的变量 值,否则就抛出一个NoSuchElementException异常。所以,除非你非常确定Optional 变量一定包含值,否则使用这个方法是个相当糟糕的主意。此外,这种方式即便相对于 嵌套式的null检查,也并未体现出多大的改进。
orElse(T other)是我们在代码清单10-5中使用的方法,正如之前提到的,它允许你在 Optional对象不包含值时提供一个默认值。
orElseGet(Supplier
Object value = map.get("key");
使用Optional封装map的返回值,你可以对这段代码进行优化。要达到这个目的有两种方式: 你可以使用笨拙的if-then-else判断语句,毫无疑问这种方式会增加代码的复杂度; 或者你可以采用Optional.ofNullable方法
Optional<Object> value = Optional.ofNullable(map.get("key"));
每次你希望安全地对潜在为null的对象进行转换,将其替换为Optional对象时,都可以考虑使用这种方法。
上一篇: 【笔记】数据类型总结