三元表达式可以产生空布尔值而不会产生编译器错误?

时间:2018-09-10 12:31:28

标签: java java-8

给出以下代码:

boolean c = true;
boolean d = true;
boolean b = c ? null : d;

System.out.println(b);

为什么编译器在这里不抱怨? 变量b是原始数据类型,null是否会产生错误消息,例如“类型不匹配:无法从null转换为boolean”?

我最好的猜测是,有一些自动装箱正在进行吗? 我在项目中看到了这段代码,但我想知道其背后的确切原因...

EDIT1: 如Mena下文所述,此代码在运行时会生成NullPointer

编辑2: 以下形式也可以正确编译:

boolean c = false;
boolean d = true;
boolean b = c ? null : d;

System.out.println(b);

编辑3: 当尝试使用编译器级别1.4进行编译时,它将无法编译,但会产生错误:

Incompatible conditional operand types null and boolean.

因此,自动装箱会很有意义,因为它是在1.5中引入的?

3 个答案:

答案 0 :(得分:1)

RHS上的表达式类型为Boolean,将在运行时自动取消装箱;编译时类型检查不会受到影响。取消装箱将导致运行时异常。

答案 1 :(得分:0)

这不能编译,因为我们不能将null值赋给原始类型的变量

boolean e = null;

这也不会编译,尽管有一个决定,编译器会检测到该值始终为空,并且与前面的情况相同

boolean f = c ? null : null;

在这种情况下,由于编译器不知道b的最终值,因此代码可以编译,但是由于最终值为null而无法运行

boolean c = true;
boolean d = true;
boolean b = c ? null : d;

答案 2 :(得分:-1)

三元表达式中的类型必须是同一类型的 ,所以我猜JLS说过,在这种情况下类型会自动装箱(它将变成{ {1}});考虑到Boolean所做的检查/优化很少,这里就不做。有趣的是,例如intellij确实会抱怨,将抛出潜力 javac

对我来说,这属于以下类别:

NullPointerException

之类的东西……对于我们来说,它们在编译时都是已知的,但对于编译器而言却不是。

一点无关,但是三元运算符离String s = null; if (true == true) { } if(s == null) { } 很远,霍尔格曾经向我展示了这个很棒的推广示例:

if statement
相关问题