Java 中是否输入了空值
Is null typed in Java
我在我的代码库中遇到了一个错误,我已经缩小到导致此行为的原因。第一个测试用例失败,而后两个测试用例成功。
@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
是一个重载方法,有两个变体,一个采用 String
,另一个采用 boolean
.
类型的原语
我怀疑这是由于自动装箱而发生的,但我不确定是否是这种情况,而且我不知道为什么 null
被转换为 Boolean
据我所知 null
不是有效的 primitive
类型。
我已经从 Apache Commons
开始使用 BooleanUtils
,我在这里问这个是为了更好地理解为什么会这样。
这个
Boolean.valueOf(nullB)
是对 Boolean#valueOf(boolean)
的调用。
它失败了,因为 Boolean
值 nullB
的拆箱失败并出现 NullPointerException
。也就是说,变成了
boolean val = nullB.booleanValue(); // at runtime nullB stores the value null
Boolean.valueOf(val)
JLS 中描述了这个过程here
If r
is a reference of type Boolean
, then unboxing conversion converts
r
into r.booleanValue()
这个
Boolean.valueOf(null)
正在调用 overloaded version that accepts a String
(since null
不是 boolean
类型的有效表达式)。
Returns a Boolean
with a value represented by the specified string.
The Boolean returned represents a true
value if the string argument is
not null
and is equal, ignoring case, to the string "true"
.
为什么第二个会成功?查看 public static Boolean valueOf(String s)
的文档:
Returns a Boolean with a value represented by the specified string.
The Boolean returned represents a true value if the string argument is not null and is equal, ignoring case, to the string "true".
你传入了一个null
,所以它会returnfalse
。
JLS中描述了重载方法解析:
15.12.2. Compile-Time Step 2: Determine Method Signature
...
- The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
在我们的例子中,在 Boolean.valueOf(boolean)
和 Boolean.valueOf(String)
之间进行选择,编译器会选择 valueOf(String)
,因为它不需要拆箱。
查看 class 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
,它将 return false,因此第二种情况成功。
在第一种情况下,关于使用 Boolean.valueOf 将数据类型作为布尔值,文档说明如下:
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
值,我想这就是它失败的原因。
我在我的代码库中遇到了一个错误,我已经缩小到导致此行为的原因。第一个测试用例失败,而后两个测试用例成功。
@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
是一个重载方法,有两个变体,一个采用 String
,另一个采用 boolean
.
我怀疑这是由于自动装箱而发生的,但我不确定是否是这种情况,而且我不知道为什么 null
被转换为 Boolean
据我所知 null
不是有效的 primitive
类型。
我已经从 Apache Commons
开始使用 BooleanUtils
,我在这里问这个是为了更好地理解为什么会这样。
这个
Boolean.valueOf(nullB)
是对 Boolean#valueOf(boolean)
的调用。
它失败了,因为 Boolean
值 nullB
的拆箱失败并出现 NullPointerException
。也就是说,变成了
boolean val = nullB.booleanValue(); // at runtime nullB stores the value null
Boolean.valueOf(val)
JLS 中描述了这个过程here
If
r
is a reference of typeBoolean
, then unboxing conversion convertsr
intor.booleanValue()
这个
Boolean.valueOf(null)
正在调用 overloaded version that accepts a String
(since null
不是 boolean
类型的有效表达式)。
Returns a
Boolean
with a value represented by the specified string. The Boolean returned represents atrue
value if the string argument is notnull
and is equal, ignoring case, to the string"true"
.
为什么第二个会成功?查看 public static Boolean valueOf(String s)
的文档:
Returns a Boolean with a value represented by the specified string. The Boolean returned represents a true value if the string argument is not null and is equal, ignoring case, to the string "true".
你传入了一个null
,所以它会returnfalse
。
JLS中描述了重载方法解析:
15.12.2. Compile-Time Step 2: Determine Method Signature
...
- The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
在我们的例子中,在 Boolean.valueOf(boolean)
和 Boolean.valueOf(String)
之间进行选择,编译器会选择 valueOf(String)
,因为它不需要拆箱。
查看 class 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
,它将 return false,因此第二种情况成功。
在第一种情况下,关于使用 Boolean.valueOf 将数据类型作为布尔值,文档说明如下:
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
值,我想这就是它失败的原因。