Java:有关 Optional 的判空 / 调试问题 ?
关系描述:
1、男孩有女朋友
2、女朋友有手提包
public class Boy { private String name;
private Girl girl;
// 省略构造方法、Getter、Setter
}
public class Girl { private String name;
private Bag bag;
// 省略构造方法、Getter、Setter
}
public class Bag { private String name;
// 省略构造方法、Getter、Setter
}
需求:根据已有的男孩实例,获取女朋友手提包的品牌名称
示例 1 - 未采用 Optional
String name = "";if (boy != null) {
Girl girl = boy.getGirl(); // 男孩关联的女孩
if (girl != null) {
Bag bag = girl.getBag(); // 女孩关联的手提包
if (bag != null) {
name = bag.getName(); // 手提包的品牌名称
}
}
}
示例 2 - 采用 Optional
name = Optional.ofNullable(boy).map(Boy::getGirl).map(Girl::getBag).map(Bag::getName).orElse("");
采用 Optional 确实代码量少了很多,但是未采用时 debug 可以 F6 一行一行的走,很快就可以知道究竟 boy、girl 或 bag 哪个对象为空,改写为采用 Optional,代码都堆在一行,还可以直观的调试出空指针在哪吗?
回答:
你这行代码的重点不是能不能直观的调试出空指针在哪,重点是这样写代码就不会出现空指针的情况。
你已经为了避免空指针的出现写了这段代码,为什么还要去纠结出了空指针在哪出的呢,根本就不会出现空指针的情况。
如果是下面这种情况,
public static void main(String[] args) { Boy boy = new Boy();
String name = Optional.ofNullable(boy).map(
b -> {
if (true) {
throw new NullPointerException();
}
return b.girl;
}).map(Girl::getBag).map(Bag::getName).orElse("");
}
是能够调试出来的,lambda$main$0(Test.java:34)
异常能够明确告诉你是哪一行出现了异常。
更新
自定义的方法
你可以自定义一个 Optional
(拷贝自 jdk 源码),来实现当 map
执行时,value 为空时,抛出空指针异常。
public final class Optional<T> { private static final Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() {
this.value = null;
}
public static <T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public boolean isPresent() {
return value != null;
}
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
Objects.requireNonNull(value);
return Optional.ofNullable(mapper.apply(value));
}
public T orElse(T other) {
return value != null ? value : other;
}
}
然后通过下面的调用方式,来确定是哪一行出现了空指针异常。
String name = Optional.ofNullable(boy) .map(Boy::getGirl)
.map(Girl::getBag)
.map(Bag::getName)
.orElse("");
黑科技方法
有一个开源项目 manifold,能够扩展原有类。
@Extensionpublic class MyOptional {
public static <T, U> Optional<U> myMap(@This Optional<T> thiz, Function<? super T, ? extends U> mapper) {
if (!thiz.isPresent()) {
throw new NullPointerException();
}
return thiz.map(mapper);
}
}
然后调用扩展方法。
String name = Optional.ofNullable(boy) .myMap(Boy::getGirl)
.myMap(Girl::getBag)
.myMap(Bag::getName)
.orElse("");
manifold
使用的是 kotlin
的思路做的,如果是在 kotlin 项目中,实现这个十分简单。
不过这种方法我在 idea 中没成功,但是可能是由于我测试的项目太复杂了,编译失败,有兴趣你可以自己研究一下。
以上是 Java:有关 Optional 的判空 / 调试问题 ? 的全部内容, 来源链接: utcz.com/p/944706.html