给出以下代码:
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中引入的?
答案 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