【发布时间】:2015-11-05 08:34:54
【问题描述】:
我在当前版本的 Java 8 中发现了一个奇怪的行为。在我看来,下面的代码应该没问题,但是 JVM 抛出了 NullPointerException:
Supplier<Object> s = () -> false ? false : false ? false : null;
s.get(); // expected: null, actual: NullPointerException
无关紧要,它是什么类型的 lambda 表达式(与 java.util.function.Function 相同)或使用什么泛型类型。也可以有更有意义的表达式来代替false ? :。上面的例子很短。这是一个更丰富多彩的例子:
Function<String, Boolean> f = s -> s.equals("0") ? false : s.equals("1") ? true : null;
f.apply("0"); // false
f.apply("1"); // true
f.apply("2"); // expected: null, actual: NullPointerException
但是这些代码片段运行良好:
Supplier<Object> s = () -> null;
s.get(); // null
和
Supplier<Object> s = () -> false ? false : null;
s.get(); // null
或带功能:
Function<String, Boolean> f = s -> {
if (s.equals("0")) return false;
else if (s.equals("1")) return true;
else return null;
};
f.apply("0"); // false
f.apply("1"); // true
f.apply("2"); // null
我用两个 Java 版本进行了测试:
~# java -version
openjdk 版本“1.8.0_66-internal” OpenJDK 运行时环境 (build 1.8.0_66-internal-b01) OpenJDK 64 位服务器 VM(内部版本 25.66-b01,混合模式)
C:\>java -version
java 版本“1.8.0_51” Java(TM) SE 运行时环境 (build 1.8.0_51-b16) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.51-b03,混合模式)
【问题讨论】:
-
这与
Object a = false ? false : false ? false : null;有何不同?NullPointerException也产生NullPointerException? -
它出现在 Java 7 和 Java 8 (OpenJDK) 中。
-
@bayou.io 怎么样? Lambdas 不添加任何东西。 “问题”是三元表达式。
-
我认为这个问题的答案是将
null拆箱为boolean值,因为在使用两个?:运算符时具有绑定/优先级。重复的帖子说了很多(也许不是关于绑定,但暗示了它)。没有必要为此发表 10 篇不同的帖子。如果您有更好的副本,我很乐意重新打开,我们可以重新关闭它。这个问题已经回答了很多次了。 -
@steffen - 显然某处有拆箱。但目前还不清楚为什么;或者它是合法的还是错误的。我敢打赌,即使是语言设计师也无法从头顶上回答这个问题。 java8 确实让
?:更加复杂。看我的分析here
标签: java lambda jvm ternary-operator