为何Optional.ifPresent在action为null且Optional为空时抛出空指针异常?
你遇到的问题并不是Optional的ifPresent方法违反了文档描述,而是实例方法引用的解析时机导致的。
先看Java文档对ifPresent的明确描述:
如果存在值,则使用该值调用指定的consumer,否则不执行任何操作。
这段描述本身没有问题,但你的代码里,uninitialisedList::add这种实例方法引用在传递给ifPresent之前,就已经触发了空指针异常——因为JVM在将实例方法引用转换为Consumer<String>对象时,需要先解析方法引用的目标对象(也就是uninitialisedList),而这个对象是null,所以在调用ifPresent方法之前,就已经抛出了NullPointerException,根本没走到Optional判断是否有值的逻辑里。
举个对比的例子,如果换成lambda表达式:
opt.ifPresent(s -> uninitialisedList.add(s));
这时候lambda表达式的内容是延迟执行的,只有当Optional存在值时才会执行uninitialisedList.add(s),如果Optional是空的,就不会执行这段代码,自然也不会触发空指针异常。
而实例方法引用uninitialisedList::add属于非捕获型的实例方法引用,它的目标对象必须在方法引用创建时就确定,JVM会先尝试获取uninitialisedList的引用,发现是null后直接抛出异常,和Optional是否为空没有关系。
简单总结:你的代码在调用ifPresent之前就已经因为null的目标对象抛出了异常,Optional的逻辑根本没机会执行。
内容的提问来源于stack exchange,提问作者pecks

