使用Optional解决空指针问题
空指针是我们最常见也最讨厌的异常,为了防止空指针异常,你不得在代码里写大量的非空判断。
Java 8引入了一个新的Optional类。用于避免空指针的出现,也无需在写大量的if(obj!=null)这样的判断了,前提是你得将数据用Optional装着,它就是一个包裹着对象的容器。
创建Optional对象
of()
为非null的值创建一个Optional。
of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。
//调用工厂方法创建Optional实例
Optional<String> name = Optional.of("Sanaulla");
//传入参数为null,抛出NullPointerException.
Optional<String> someNull = Optional.of(null);
ofNullable()
为指定的值创建一个Optional,如果指定的值为null,则返回一个空的(empty)Optional。
ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况。示例如下:
//下面创建了一个不包含任何值的Optional实例
Optional empty = Optional.ofNullable(null);
常用api解释
isPresent()
如果存在值就返回true,否则返回false。
if (name.isPresent()) {
//在Optional实例内调用get()返回已存在的值
System.out.println(name.get());//输出Sanaulla
}
get()获取其中的数据
如果Optional中有值则将其返回,否则抛出NoSuchElementException。
ifPresent(consumer)
如果Optional实例有值则调用consumer,否则不做处理
要理解ifPresent方法,首先需要了解Consumer类。简答地说,Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。
name.ifPresent((value) -> {
System.out.println("The length of the value is: " + value.length());
});
orElse(default)
如果有值则将其返回,否则返回指定的默认值。
如果Optional实例有值则将其返回,否则返回orElse方法传入的参数。
empty.getElse("default");
orElseGet()
orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。
empty.orElseGet(()-> "default value")
orElseThrow()
如果有值则将其返回,否则抛出supplier接口创建的异常。
try {
empty.orElseThrow(()->new RuntimeException());
} catch (Throwable ex) {
//输出: No value present in the Optional instance
System.out.println(ex.getMessage());
}
上代码:
import java.util.Date;
import java.util.Optional;
/**
* @author qiang.xie
* @date 2017/5/15
*/
public class OptionalTest {
public static void main(String[] arg) {
//创建Optional对象,如果参数为空直接抛出异常
Optional<String> str=Optional.of("a");
//获取Optional中的数据,如果不存在,则抛出异常
System.out.println(str.get());
//optional中是否存在数据
System.out.println(str.isPresent());
//获取Optional中的值,如果值不存在,返回参数指定的值
System.out.println(str.orElse("b"));
//获取Optional中的值,如果值不存在,返回lambda表达式的结果
System.out.println(str.orElseGet(()->new Date().toString()));
//获取Optional中的值,如果值不存在,抛出指定的异常
System.out.println(str.orElseThrow(()->new RuntimeException()));
Optional<String> str2=Optional.ofNullable(null);
//optional中是否存在数据
System.out.println(str2.isPresent());
//获取Optional中的值,如果值不存在,返回参数指定的值
System.out.println(str2.orElse("b"));
//获取Optional中的值,如果值不存在,返回lambda表达式的结果
System.out.println(str2.orElseGet(()->new Date().toString()));
//获取Optional中的值,如果值不存在,抛出指定的异常
System.out.println(str2.orElseThrow(()->new RuntimeException()));
}
}
运行结果:
a
true
a
a
a
false
b
Mon May 15 20:22:47 CST 2017
Exception in thread "main" java.lang.RuntimeException
at OptionalTest.lambda$main$3(OptionalTest.java:42)
at OptionalTest$$Lambda$4/931919113.get(Unknown Source)
at java.util.Optional.orElseThrow(Optional.java:290)
at OptionalTest.main(OptionalTest.java:42)
以后,设计一个方法时,考虑将返回值用Optional包裹着吧。
@不迷失|知识改善生活
微信公众号:java技术
1492957339专注技术研究与视频教学,分享有价值的技术与经验,关注程序员的发展!
技术博客:http://bumishi.cn
技术交流群:245130488
@不迷失教学视频
xiaoetong_qrcode
qqketang_qrcode腾讯课堂:http://bumishi.ke.qq.com
百度课堂:http://chuanke.com/s3377987.html
网友评论