我在代码库中遇到了一个错误,我已经缩小到导致这种行为的原因.第一个测试用例失败,而后两个失败.
@Test
public void testBooleanNull1() {
Boolean nullB = null;
assertFalse(Boolean.valueOf(nullB));
}
@Test
public void testBooleanNull2() {
String nullS = null;
assertFalse(Boolean.valueOf(nullS));
}
@Test
public void testBooleanNull3() {
assertFalse(Boolean.valueOf(null));
}
Run Code Online (Sandbox Code Playgroud)
我知道这Boolean.valueOf是一个重载方法,有两个变量,一个采用a String,另一个采用类型的原语boolean.
我怀疑这是因为自动装箱而发生,但我不确定是否是这种情况,而且我不知道为什么null被转换为a Boolean,据我所知null不是有效primitive类型.
我已经转而使用BooleanUtils了Apache Commons,我在这里问这个更好地理解为什么这种行为是这样的.
Sot*_*lis 31
这个
Boolean.valueOf(nullB)
Run Code Online (Sandbox Code Playgroud)
是一个调用Boolean#valueOf(boolean).
它失败,因为Boolean值的取消装置nullB失败了NullPointerException.换句话说,它变成了
boolean val = nullB.booleanValue(); // at runtime nullB stores the value null
Boolean.valueOf(val)
Run Code Online (Sandbox Code Playgroud)
此过程在JLS中进行了描述
如果
r是类型的引用Boolean,则取消装箱转换将转换r为r.booleanValue()
这个
Boolean.valueOf(null)
Run Code Online (Sandbox Code Playgroud)
正在调用接受aString的重载版本(因为null它不是类型的有效表达式boolean).
返回
Boolean带有指定字符串表示的值的a.返回的布尔值表示一个true值,如果字符串参数不是null并且与字符串相同,则忽略大小写"true".
JLS中描述了重载的方法解析:
15.12.2.编译时间步骤2:确定方法签名
...
- 第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用.如果在此阶段没有找到适用的方法,则处理继续到第二阶段.
在我们的例子中,选择Boolean.valueOf(boolean)和Boolean.valueOf(String)编译器选择,valueOf(String)因为它不需要拆箱.