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,能够扩展原有类。

@Extension

public 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

回到顶部