以下代码段会引发NullPointerException
。我想了解if
条件的工作流程。如果只有true
和false
是if
条件的有效参数,为什么Java编译器不会抛出错误?
Boolean booleanFlag = null;
if(booleanFlag) {
System.out.println("Why this boolean flag code is executed?");
}
答案 0 :(得分:6)
这与Java的一个名为auto(un)boxing的功能有关。基本上,在编译器中,编译器将此代码转换为:
if (booleanFlag.booleanValue()) {
//..
}
现在,如果booleanFlag是null
,那么它会在运行时抛出NPE
。这就是Joshua Bloch所说的“autoboxing blurs,但不会消除原始类型和盒装等价物之间的鸿沟”。
也许在这种特殊情况下,初始化的盒装原语编译器至少可以生成警告,但一般来说,生成这样的警告是不可能的。
答案 1 :(得分:5)
Java编译器确实根据任何数据流分析提供错误(除了检查变量是否已初始化,并且在这种情况下,您已将其初始化为null
)。完全没有意识到booleanFlag
的值在执行中的那一点必然是null
。
至于为什么,我只能推测语言作者知道这样的功能会给语言增加太多的复杂性,并且会给编译器带来太多的性能成本。
答案 2 :(得分:3)
java.lang.Boolean类在对象中包装基本类型boolean的值。 Boolean类型的对象包含一个类型为boolean的字段。
答案 3 :(得分:1)
Java语言定义包括自动“装箱”和“拆箱”的概念
这允许原始类型(boolean
,int
,double
等)自动转换为Object
等价物(装箱)和{{1}等对象},Boolean
等转换为基元(拆箱)
但是取消装箱要求对象(例如Integer
)不为空。如果它为null,则表示运行时错误(Boolean
)。它必须是运行时错误,因为该语言无法提供足够的信息来在编译时始终检测空条件。
在您的情况下,编译器正在尝试将您的NullPointerException
取消装入Boolean booleanFlag
,以便它可用于boolean
条件,并且转换失败。