在Java中为null类型

在Java中为null类型,java,types,null,Java,Types,Null,我在我的代码库中遇到了一个bug,我已经缩小了导致这种行为的范围。第一个测试用例失败,而最后两个成功 @Test public void testBooleanNull1() { Boolean nullB = null; assertFalse(Boolean.valueOf(nullB)); } @Test public void testBooleanNull2() { String nullS = null; assertFalse(Boolean.va

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

@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));
}
我知道
Boolean.valueOf
是一个重载方法,有两个变体,一个是
字符串,另一个是
Boolean
类型的原语

我怀疑发生这种情况是因为自动装箱,但我不确定是否是这种情况,而且我不知道为什么
null
被转换为
Boolean
,据我所知
null
不是有效的
基本类型

我从apachecommons开始使用BooleanUtils,我在这里问这个问题是为了更好地理解为什么行为是这样的。

Boolean.valueOf(nullB)
是一种对语言的调用

它失败是因为
Boolean
nullB
的取消装箱失败,出现
NullPointerException
。换句话说,它变成了

boolean val = nullB.booleanValue(); // at runtime nullB stores the value null
Boolean.valueOf(val)
JLS中描述了此过程

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

这个

正在调用(因为不是类型为
boolean
的有效表达式)

返回一个
布尔值
,其值由指定的字符串表示。 如果字符串参数为,则返回的布尔值表示
true
值 not
null
,忽略大小写,等于字符串
“true”


为什么第二个会成功?请看以下文件:

返回一个布尔值,该值由指定的字符串表示。 如果字符串参数为非null,并且忽略大小写,等于字符串“true”,则返回的布尔值表示真值


您在中传递了一个
null
,因此它将返回
false

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

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

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

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

    查看类
    Boolean

    public static Boolean valueOf(String s) {
        return toBoolean(s) ? TRUE : FALSE;
    }
    
    。。然后:

    private static boolean toBoolean(String name) {
       return ((name != null) && name.equalsIgnoreCase("true"));
    }
    
    如果
    Boolean.valueOf(String s)
    的字符串参数为
    null
    ,它将返回false,因此第二种情况成功

    在第一种情况下,关于Boolean.valueOf的使用,其数据类型为Boolean,以下是文档说明:

    public static Boolean valueOf(boolean b)
    
    Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance.
    
    Parameters:
    b - a boolean value.
    Returns:
    a Boolean instance representing b.
    

    这里需要的参数是一个
    boolean
    值,它接受
    True
    False
    ,而不是
    boolean
    值,它接受
    True
    False
    null
    。由于您传递了一个
    Boolean
    值,而不是
    Boolean
    值,我想这就是它失败的原因

    请看这个答案一针见血!
    public static Boolean valueOf(boolean b)
    
    Returns a Boolean instance representing the specified boolean value. If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE. If a new Boolean instance is not required, this method should generally be used in preference to the constructor Boolean(boolean), as this method is likely to yield significantly better space and time performance.
    
    Parameters:
    b - a boolean value.
    Returns:
    a Boolean instance representing b.