Java if语句检查null,但仍然抛出NullPointerException

Java if语句检查null,但仍然抛出NullPointerException,java,nullpointerexception,Java,Nullpointerexception,在这个代码中 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 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”


假设传递给
testFun
的实际参数的值是从某个进程生成的。假设该进程错误地返回了一个
null
值,并将其提供给testFun。如果是这种情况,如何验证传递给函数的值是否为null


一种(奇怪的)解决方案可能是将形式参数指定给函数中的某个变量,然后对其进行测试。但是,如果有许多变量传递给函数,这可能会变得单调乏味且不可行。那么,在这种情况下如何检查空值呢?

这里的问题是,在您的代码中,程序正在调用“null.length()”,如果传递给函数的参数为空,则不会定义该参数。这就是引发异常的原因。

问题在于您使用的是按位or运算符:
|
。如果使用逻辑or运算符,
|
,代码将正常工作

另请参见:


编辑准确地显示了有效代码和无效代码之间的差异

此检查始终评估这两个条件,如果
str
为空,则引发异常:

 if (str == null | str.length() == 0) {
而这(使用
|
而不是
|
)是短路-如果第一个条件的计算结果为
,则第二个条件不计算

有关
|
和二进制
|
的说明,请参阅JLS的第页。第15.24节的介绍是重要的一点:

条件or运算符| |运算符类似于|(§15.22.2),但仅当其左侧操作数的值为false时才计算其右侧操作数


您可以使用
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");

}
请看这里:

isBlank
示例:

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

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


现在,您的代码将正确运行。确保
str.isEmpty()
位于
str==null
之后,因为在null上调用
isEmpty()
将导致
NullPointerException
。由于Java在
str==null
为真时使用短路求值,因此它不会求值
str.isEmpty()
并且每次都检查两侧(&p)

如果(str==null | str.length()==0)

这里我们很有可能得到NullPointerException

逻辑| |和&&仅在必要时检查右侧

但是使用逻辑运算符

没有机会获得NPE,因为它不会检查RHS


在if(str==null | | | str.length()==0)条件下,如果第一部分为false,则永远不会计算第二部分。如果确实希望对第二部分进行求值,那么可以将其编写为(str==null | str.length()==0),这样就可以得到一个null指针。我不明白在这种情况下你为什么想要它,但在某些情况下,这可能是有益的。事实上确实如此他很懒,但他用|来评估两者sides@baba我得到了它。很好<代码>| |作为短路操作员工作,因此一旦评估为真,它将不会到达下一部分。在使用
|
时,计算null.length,这会产生异常
if (str == null || str.isEmpty()) {