38

在这段代码中。

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并打印“字符串为空”?


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

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

4

6 回答 6

71

编辑准确地显示了有效代码和无效代码之间的区别。

此检查始终评估这两个str条件,如果为 null ,则抛出异常:

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

而这(使用||而不是|)是短路的- 如果第一个条件评估为true,则不评估第二个条件。

请参阅JLS 的第15.24节以了解对. 不过,第 15.24 节的介绍很重要:|||

条件或运算符 || 运算符就像 | (§15.22.2),但仅当其左侧操作数的值为假时才评估其右侧操作数。

于 2012-08-26T19:59:52.970 回答
9

您可以使用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
于 2015-06-25T08:48:44.160 回答
5

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

于 2012-08-26T19:50:55.950 回答
4

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

另请参阅:
http ://en.wikipedia.org/wiki/Short-circuit_evaluation
Java 中 & 和 && 的区别?

于 2012-08-26T19:57:59.743 回答
1

更改下一行

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

进入

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

现在您的代码将正确运行。确保str.isEmpty()紧随其后,str == null因为调用isEmpty()null 会导致NullPointerException. 因为Java在为真时使用短路评估str == null,所以它不会评估str.isEmpty()

于 2019-07-22T11:05:02.257 回答
0

该| 和 & 每次检查双方。

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

在这里我们很有可能得到 NullPointerException

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

但有逻辑运算符

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

于 2020-02-04T07:23:08.323 回答