if语句检查null,但仍会抛出NullPointerException异常。

39

在这段代码中。

public class Test {
     public static void testFun(String str) {
         if (str == null | str.length() == 0) {
             System.out.println("String is empty");
         } else { 
             System.out.println("String is not empty");
         }
     }
     public static void main(String [] args) {
         testFun(null);
    }
}

我们将一个null值传递给函数testFun。编译没有问题,但在运行时会抛出NullPointerException异常,这是我没有预料到的。为什么它会抛出异常,而不是评估if条件为true并打印"String is empty"?


假设实际参数的值是由某个过程生成的。假设该过程错误地返回了一个null值,并被输入到testFun中。如果是这种情况,如何验证传递给函数的值是否为null?

一种(奇怪)的解决方案可能是在函数内部将形式参数赋值给某个变量,然后进行测试。但是如果有许多变量传递到函数中,那可能变得繁琐和不可行。那么,在这种情况下如何检查null值?

6个回答

72
这篇编辑清楚地展示了可用和不可用的代码之间的差异。
这个检查总是评估两个条件,如果str为空,则抛出异常。
 if (str == null | str.length() == 0) {

使用||而不是|,可以实现短路 - 如果第一个条件评估为true,则不评估第二个条件。请参见JLS的section 15.24中对||的描述,以及section 15.22.2中对二进制|的描述。但是,第15.24节的介绍是重要的部分:

条件或运算符||运算符类似于|(§15.22.2),但仅在其左操作数的值为false时评估其右操作数的值。


10

您可以使用StringUtils

import org.apache.commons.lang3.StringUtils;

if (StringUtils.isBlank(str)) {

System.out.println("String is empty");

} else { 

System.out.println("String is not empty");

}

这里也可以看一下:StringUtils.isBlank() vs String.isEmpty()

isBlank 的例子:

StringUtils.isBlank(null)      = true
StringUtils.isBlank("")        = true  
StringUtils.isBlank(" ")       = true  
StringUtils.isBlank("bob")     = false  
StringUtils.isBlank("  bob  ") = false

5
这里的问题在于你的代码调用了“null.length()”,如果传递给函数的参数为null,则未定义该方法。这就是为什么会抛出异常的原因。

2
如果 str == null,则不会进入 if 的那一部分。 - Keppil
2
在 if (str == null || str.length() == 0) 的条件中,如果第一个条件为假,则第二个条件永远不会被评估。如果您确实希望对第二部分进行评估,则应将其编写为 if (str == null | str.length() == 0),这样您就可以获得 nullpointer。虽然我不知道在这种情况下为什么要这样做,但在某些情况下,这可能是有益的。 - Nikola Yovchev
2
实际上它确实会这样做。|| 是懒惰的,但他使用 | 会评估两边。 - Zoltan Balazs
@baba 我明白了。好观点。||作为短路运算符,一旦评估为真,它就不会到达下一部分。由于使用了|,因此评估了null.length,这导致了异常的产生。 - Shades88

4

1

更改以下行

if (str == null | str.length() == 0) {

转换为

if (str == null || str.isEmpty()) {

现在你的代码将正常运行。请确保str == null之后再调用str.isEmpty(),因为在空值上调用isEmpty()会导致NullPointerException异常。由于Java使用短路求值,当str == null为真时,它不会计算str.isEmpty()


0

| 和 & 每次都会检查两侧。

if (str == null | str.length() == 0)

这里有很高的可能性会得到 NullPointerException。

逻辑运算符 || 和 && 只在必要时才检查右侧。

但是使用逻辑运算符

不可能出现 NPE,因为它不会检查 RHS


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接