Java中Optional.orElseGet()两种写法执行结果不同的原因咨询
为什么Optional.orElseGet中方法引用和Lambda表达式表现不同?
先看你给出的代码:
String text = "hi"; String text2 = null; // 第一段代码抛出NullPointerException System.out.println(Optional.ofNullable(text).map(String::length).orElseGet(text2::length)); // 第二段代码输出"2" System.out.println(Optional.ofNullable(text).map(String::length).orElseGet(() -> text2.length()));
核心原因在于方法引用与Lambda表达式的执行时机差异:
实例方法引用
text2::length的解析是即时的:
当你把text2::length作为参数传递给orElseGet时,Java需要先解析这个方法引用对应的实例对象(也就是text2)。因为text2是null,JVM在构造这个方法引用的瞬间就会抛出NullPointerException——这个过程发生在orElseGet方法执行之前,和Optional是否有值完全无关。Lambda表达式
() -> text2.length()是延迟执行的:
Lambda的代码体只有在orElseGet方法需要调用Supplier.get()时才会执行。这里Optional.ofNullable(text)不为空,map操作后得到包含2的Optional,所以orElseGet直接返回已有值,根本不会触发Lambda的执行,自然不会去调用text2.length(),也就不会出现空指针异常。
补充验证:如果把text设为null,两段代码都会抛出NullPointerException——这时候orElseGet会执行Supplier.get(),第二段的Lambda会执行text2.length(),同样触发空指针。
内容的提问来源于stack exchange,提问作者Juan2
相关产品推荐
相关产品推荐

