在 Java 中键入空值

2022-09-01 14:25:32

我在代码库中遇到了一个错误,我已经缩小到导致这种行为的原因。第一个测试用例失败,而最后两个测试用例成功。

@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));
}

我知道这是一个重载方法,有两个变体,一个取a,另一个取一个类型的基元。Boolean.valueOfStringboolean

我怀疑这是由于自动装箱而发生的,但我不确定是否如此,而且我不知道为什么被转换为据我所知不是有效的类型。nullBooleannullprimitive

我已经转向使用 from ,我在这里问这个问题是为了更好地理解为什么行为是这样的。BooleanUtilsApache Commons


答案 1

Boolean.valueOf(nullB)

是对布尔值#valueOf(布尔值)的调用。

它失败,因为值的取消装箱失败,并带有 .换句话说,它变成了BooleannullBNullPointerException

boolean val = nullB.booleanValue(); // at runtime nullB stores the value null
Boolean.valueOf(val)

此过程在 JLS 中进行了描述

如果 是 类型的引用,则取消装箱转换将转换为rBooleanrr.booleanValue()

Boolean.valueOf(null)

正在调用接受 String 的重载版本(因为 null 不是类型的有效表达式)。boolean

返回 具有由指定字符串表示的值的 。如果字符串参数不是,则返回的布尔值表示一个值,并且等于字符串,忽略大小写。Booleantruenull"true"


答案 2

重载方法解析在 JLS 中描述:

15.12.2. 编译时步骤 2:确定方法签名

...

  1. 第一阶段 (§15.12.2.2) 执行重载解析,不允许装箱或取消装箱转换,也不允许使用可变 arity 方法调用。如果在此阶段找不到适用的方法,则处理将继续到第二阶段。

在我们的例子中,在和编译器之间进行选择是因为它不需要拆箱。Boolean.valueOf(boolean)Boolean.valueOf(String)valueOf(String)