Version: Next
Optional类
info
优雅的处理一种大家经常写的代码
if (userName != null) { // 判空
//...
} else {
// ..
}
Java的经典送命祖传异常,空指针异常
Optional<T>
类,java.util.Optional
是一个容器类
- 它可以保存T的值,代表这个值存在
- 或者仅仅保存null,表示这个值不存在
- 原来用
null
表示一个值存不存在,现在用Optional
来更好的表达这个概念,并且可以避免空指针异常Optional
类的JavaDoc
描述为,这是一个可以为null
的容器对象
- 如果值存在:
isPresent()
方法返回true
get()
方法,可以返回该对象
Api
创建Optional类对象的方法
Optional.of(T t)
:创建一个Optional
实例,t
必须非空,否则抛出空指针异常Optional.empty()
:创建一个空的Optional
实例Optional.ofNullable(T t)
:t
可以为空
判断Optional容器中是否包含对象
boolean isPresent()
:判断是否包含对象void ifPresent(Consumer<? super T> consumer)
:如果有值
,就执行Consumer中接口方法accept()
的实现代码,并且该值
会作为参数传递给它
,即accept(值)
。
获取Optional容器中的对象
T get()
:如果调用对象包含值,返回该值,否则抛出异常T orElse(T other)
:如果有值将其返回,否则返回指定的other对象T orElseGet(Supplier<? extends T> other)
:如果有值将其返回,否则返回Supplier接口实现提供的对象T orElseThrow(Supplier<? extends X> exceptionSupplier)
:如果有值则将其返回,否则抛出由Supplier接口实现提供的异常
举例说明Optional的使用
直观的写法
获取男孩的女朋友的名字
经典空指针判断
public static String getGirlName(Boy boy) {
if (boy != null) {
Girl girl = boy.getGirl();
if (girl != null)
return girl.getName();
}
}
return null;
}
info
使用Optional
使用Optional
public static String getGirlNameByOptional(Boy boy) {
// boy本身就可能是null,所以用ofNullable来创建Optional实例
Optional<Boy> optionalBoy = Optional.ofNullable(boy);
// boy不是空,就拿他女朋友; boy是空就给他一个空气女朋友
Boy resultBoy = optionalBoy.orElse(new Boy(new Girl("不存在的女生"), "备胎舔狗"));
// 还要判断:如果传进来的Boy不是空,那要看看他的女票是不是空的
Optional<Girl> optionalGirl = Optional.ofNullable(resultBoy.getGirl());
Girl resultGirl = optionalGirl.orElse(new Girl("不存在的女生"));
return resultGirl.getName();
}
另一种简洁写法
- 经典
public static String getGirlName(Boy boy) {
if (boy == null) { // 男孩为空
return null;
}
if (boy.getGirl() == null) { // 男孩的女票为空
return null;
}
if (boy.getGirl().getName() == null) { // 男的女票的名字为空
return null;
}
return boy.getGirl().getName();
}
- Optional
map和flatMap的区别
map会自动返回Optional类型
flatMap不会自动返回Optional类型,需要你自己确保返回的东西是Optional类型
public static String getGirlNameByOptional(Boy boy) {
String girlName = Optional.ofNullable(boy) // 实例化Optional
// 男孩不为空,拿他女票做Optional
.flatMap((Boy boy1) -> Optional.ofNullable(boy1.getGirl()))
// 女票不为空,那就拿女孩的名字做Optional
.map(Girl::getName).orElse("空气女朋友"); //男的、男的女朋友、女的名字 任意一个出现null值,就返回“空气女盆友”
return girlName;
}
测试
boy存在,但是他没女票 (null)
public static void main(String[] args) {
Boy boy = new Boy();
// boy = null;
// Boy boy = new Boy(new Girl(null), "王大锤");
// Boy boy = new Boy(new Girl("铃科百合子"), "王大锤");
String girlName = getGirlNameByOptional(boy);
System.out.println("girlName = " + girlName);
}
运行结果
girlName = 空气女朋友
boy不存在 (null)
public static void main(String[] args) {
Boy boy = new Boy();
boy = null;
// Boy boy = new Boy(new Girl(null), "王大锤");
// Boy boy = new Boy(new Girl("铃科百合子"), "王大锤");
String girlName = getGirlNameByOptional(boy);
System.out.println("girlName = " + girlName);
}
运行结果
girlName = 空气女朋友
boy存在,名叫王大锤,有个女票,但是不知道女票的名字 (null)
public static void main(String[] args) {
// Boy boy = new Boy();
// boy = null;
Boy boy = new Boy(new Girl(null), "王大锤");
// Boy boy = new Boy(new Girl("铃科百合子"), "王大锤");
String girlName = getGirlNameByOptional(boy);
System.out.println("girlName = " + girlName);
}
运行结果
girlName = 空气女朋友
boy存在,名叫王大锤,有个女票,名叫铃科百合子 (not null)
public static void main(String[] args) {
// Boy boy = new Boy();
// boy = null;
// Boy boy = new Boy(new Girl(null), "王大锤");
Boy boy = new Boy(new Girl("铃科百合子"), "王大锤");
String girlName = getGirlNameByOptional(boy);
System.out.println("girlName = " + girlName);
}
运行结果
girlName = 铃科百合子