如果您花了一些时间在 Java 中开发程序,那么在某些时候您肯定会看到以下异常:
java.lang.NullPointerException
由于NullPointerException
原因,出现了一些主要的生产问题。在本文中,我们将介绍一些在 Java 中处理NullPointerException
的方法。
简单空检查
请考虑以下代码段:
public static void main(String args[]) {
String input1 = null;
simpleNullCheck(input1);
}
private static void simpleNullCheck(String str1) {
System.out.println(str1.length());
}
如果按原样运行此代码,将出现以下异常:
Exception in thread "main" java.lang.NullPointerException
您收到此错误的原因是因为我们正在尝试对str1
执行length()
操作,str1
是null
。
一个简单的解决方法是对str1
添加空检查,如下所示:
private static void simpleNullCheck(String str1) {
if (str1 != null) {
System.out.println(str1.length());
}
}
这将确保在str1是
null
时不会在其上运行length()
函数。
但您可能有以下问题。
如果str1是一个重要的变量呢?
在这种情况下,您可以尝试如下操作:
private static void simpleNullCheck(String str1) {
if (str1 != null) {
System.out.println(str1.length());
} else {
// Perform an alternate action when str1 is null
// Print a message saying that this particular field is null and hence the program has to stop and cannot continue further.
}
}
这个想法是,当你期望一个值可能为null
时,最好对该变量进行null
检查。如果结果确实是null
值,请采取替代措施。
这不仅适用于字符串,也适用于 Java 中的任何其他对象。
Lombok空检查
现在以以下示例为例:
public static void main(String args[]) {
String input2 = "test";
List<String> inputList = null;
lombokNullCheck(input2, inputList, input2);
}
public static void lombokNullCheck(String str1, List<String> strList, String str2) {
System.out.println(str1.length() + strList.size() + str2.length());
}
这里我们有一个接受三个参数的函数:str1
,strList
和str2
。
如果这些值中的任何一个被证明是null
,我们根本不想执行这个函数中的逻辑。
您如何实现这一目标?
这就是龙目岛派上用场的地方。为了在代码中添加龙目岛库,请包含以下 Maven 依赖项:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
要了解有关Maven的更多信息,请查看本文。
以下是龙目岛检查null
的代码:
public static void main(String args[]) {
String input2 = "test";
List<String> inputList = null;
try {
lombokNullCheck(input2, inputList, input2);
} catch (NullPointerException e) {
System.out.println(e);
}
}
public static void lombokNullCheck(@NonNull String str1, @NonNull List<String> strList, @NonNull String str2) {
System.out.println(str1.length() + strList.size() + str2.length());
}
在函数的每个参数之前,我们添加@NonNull
注释。
同样,当我们调用这个函数时,我们在函数调用周围放置一个try-catch
块来捕获NullPointerException
。
如果函数中给出的任何参数被证明是null
,则该函数将抛出NullPointerException
。然后,这将被try-catch
块捕获。
这确保了,如果任何函数参数被证明是null
,那么函数中的逻辑就不会被执行,我们知道代码不会异常。
这也可以通过一堆null
检查语句来完成。但是使用 Lombok 可以帮助我们避免编写一堆null
检查语句,并使代码看起来更干净。
列表和空值
假设您有一个列表,并且想要打印列表中的所有元素:
List<String> stringList = new ArrayList<>();
stringList.add("ele1");
stringList.add("ele2");
if (stringList != null) {
for (String element : stringList)
System.out.println(element);
}
在循环访问列表之前,我们需要在列表上进行null检查
。
如果null
检查不存在,则尝试循环 null
将抛出 NullPointerException
。
映射和空值
让我们以需要访问映射中特定键的值的场景为例:
Map<String, String> testMap = new HashMap<>();
testMap.put("first_key", "first_val");
if (testMap != null && testMap.containsKey("first_key")) {
System.out.println(testMap.get("first_key"));
}
首先,我们需要对 map 对象本身进行空检查。如果不这样做,并且地图是null
,那么抛出NullPointerException
。这是使用testMap!=null
完成此操作后,在访问特定密钥之前检查是否存在该密钥。您可以使用testMap.containsKey("first_key")
命令检查密钥是否存在。如果未执行此操作并且缺少特定键,则将获得值 null
。
是否有必要始终添加空检查?
如果您确定特定变量永远不可能null
,那么您可以避免添加null
检查。这可能适用于私有函数,您可以在其中控制进入函数的数据。
但是,如果您不确定对象的可空性,最好添加null
检查。
源码下载
本文中讨论的所有代码都可以在此 Github 存储库中找到。
恭喜?
你现在知道在Java中是如何处理NullPointerException
了!