介绍
在这个实验中,我们将探索不同的技术来检查 Java 中的 ArrayList 是否为 null。处理 null 值是健壮的 Java 编程的一个基本方面,理解如何正确处理 null 值对于防止 NullPointerException 错误至关重要。
我们将首先研究使用相等运算符 (==) 直接检查 null 的最基本方法。接下来,我们将学习如何将 null 检查与空列表检查相结合,以有效处理这两种情况。最后,我们将探索 Optional 类的使用,这是 Java 的一个现代特性,它提供了一种更具表现力和更安全的方式来处理可能为 null 的值。
使用相等运算符进行空值检查
在这一步中,我们将探索在 Java 中检查变量是否为 null 值的最基本方法:使用相等运算符 (==)。理解如何处理 null 在 Java 编程中至关重要,可避免出现错误。
在 Java 中,null 是一个特殊的值,表示变量不引用任何对象。可以把它想象成一个空盒子 —— 盒子存在,但里面什么都没有。如果你尝试像使用对象一样使用一个值为 null 的变量(比如调用它的方法),就会得到一个 NullPointerException,这是 Java 中非常常见的错误。
相等运算符 (==) 用于比较两个值。当将对象引用与 null 进行比较时,== 会检查该引用是否指向 null 值。
让我们创建一个简单的 Java 程序来演示这一点。
如果
HelloJava.java文件尚未在 WebIDE 编辑器中打开,请打开它。将文件的全部内容替换为以下代码:
public class HelloJava { public static void main(String[] args) { String message = null; // Declaring a String variable and setting it to null // Checking if the message variable is null if (message == null) { System.out.println("The message is null."); } else { System.out.println("The message is not null: " + message); } message = "Hello, World!"; // Assigning a String object to the variable // Checking again after assigning a value if (message == null) { System.out.println("The message is null."); } else { System.out.println("The message is not null: " + message); } } }在这段代码中:
- 我们声明了一个名为
message的String变量,并将其初始值设为null。 - 我们使用一个
if语句,条件为message == null,来检查该变量是否为null。 - 我们打印一条消息,表明该变量是否为
null。 - 然后,我们将一个实际的
String值("Hello, World!")赋给message变量。 - 我们再次进行
null检查,以查看差异。
- 我们声明了一个名为
保存文件(Ctrl+S 或 Cmd+S)。
在终端中使用
javac命令编译程序:javac HelloJava.java如果没有错误,编译将无声地完成。
使用
java命令运行编译后的程序:java HelloJava你应该会看到以下输出:
The message is null. The message is not null: Hello, World!这个输出证实了
== null检查能够正确识别message变量何时为null以及何时有值。
使用相等运算符 (==) 是在 Java 中检查 null 的最直接方法。不过,要记住这仅适用于检查引用是否为 null。它不会检查字符串是否为空(不包含任何字符,如 "")。我们将在下一步中探索如何处理空字符串。
结合空值和空字符串检查
在上一步中,我们学习了如何使用 == 运算符检查变量是否为 null。然而,在 Java 中,尤其是处理 String 对象时,通常不仅需要检查变量是否为 null,还需要检查它是否“为空”。空字符串是一个存在但不包含任何字符的 String 对象(例如 "")。而 null 字符串则表示该变量根本不引用任何 String 对象。
尝试对 null 字符串调用 isEmpty() 或 length() 等方法会导致 NullPointerException。因此,当你想以相同的方式处理 null 字符串和空字符串时(例如,将它们视为“空白”或“缺失”),就需要同时检查这两种情况。
最常见的做法是先检查字符串是否为 null,如果不是 null,再使用 isEmpty() 方法检查它是否为空。
让我们修改 HelloJava.java 程序来演示如何结合这些检查。
在 WebIDE 编辑器中打开
HelloJava.java文件。将当前代码替换为以下内容:
public class HelloJava { public static void main(String[] args) { String text1 = null; String text2 = ""; // An empty string String text3 = "Hello"; // A non-empty string System.out.println("Checking text1 (null):"); if (text1 == null || text1.isEmpty()) { System.out.println("text1 is null or empty."); } else { System.out.println("text1 is not null and not empty: " + text1); } System.out.println("\nChecking text2 (empty):"); // It's crucial to check for null first! if (text2 == null || text2.isEmpty()) { System.out.println("text2 is null or empty."); } else { System.out.println("text2 is not null and not empty: " + text2); } System.out.println("\nChecking text3 (not empty):"); if (text3 == null || text3.isEmpty()) { System.out.println("text3 is null or empty."); } else { System.out.println("text3 is not null and not empty: " + text3); } } }在这个更新后的代码中:
- 我们引入了三个
String变量:text1(null)、text2(空字符串)和text3(非空字符串)。 - 我们使用逻辑或运算符 (
||) 来结合null检查 (text == null) 和空字符串检查 (text.isEmpty())。 - 条件
text == null || text.isEmpty()在text为null或者text不为null且text.isEmpty()为true时为true。 - 重要提示:
null检查 (text == null) 必须在||条件中排在首位。如果text为null,||条件的第一部分 (text == null) 为true,Java 会使用“短路求值”跳过第二部分 (text.isEmpty()),从而避免NullPointerException。如果isEmpty()检查排在首位且text为null,则会导致错误。
- 我们引入了三个
保存文件(Ctrl+S 或 Cmd+S)。
在终端中编译程序:
javac HelloJava.java运行程序:
java HelloJava你应该会看到以下输出:
Checking text1 (null): text1 is null or empty. Checking text2 (empty): text2 is null or empty. Checking text3 (not empty): text3 is not null and not empty: Hello这个输出表明,我们的组合检查正确地将
null字符串 (text1) 和空字符串 (text2) 识别为“null或为空”,同时也正确地识别出了非空字符串 (text3)。
这种组合检查 (string == null || string.isEmpty()) 是 Java 中处理 null 字符串和空字符串时非常常见的模式。许多库也为此提供了实用方法,例如 Apache Commons Lang 中的 StringUtils.isEmpty() 或 StringUtils.isBlank()(还会检查是否为空白字符),但理解基本的组合检查是基础。
使用 Optional 进行安全处理
虽然使用 == null || isEmpty() 来检查 null 和空字符串很有效,但 Java 8 引入了 Optional 类,以更明确、安全的方式处理可能缺失的值。Optional 是一个容器对象,它可能包含也可能不包含非 null 值。通过使用 Optional,你可以避免 NullPointerException,并通过明确表明某个值可能缺失来使代码更具可读性。
Optional 并不能完全替代 null 检查,但它提供了一种更具函数式风格和表现力的方式来处理值可能缺失的情况。
让我们看看如何在 HelloJava.java 程序中使用 Optional。
在 WebIDE 编辑器中打开
HelloJava.java文件。将当前代码替换为以下内容:
import java.util.Optional; public class HelloJava { public static void main(String[] args) { String text1 = null; String text2 = ""; String text3 = "Hello"; // Creating Optional objects Optional<String> optionalText1 = Optional.ofNullable(text1); Optional<String> optionalText2 = Optional.ofNullable(text2); Optional<String> optionalText3 = Optional.ofNullable(text3); System.out.println("Checking optionalText1 (from null):"); // Check if a value is present if (optionalText1.isPresent()) { System.out.println("optionalText1 contains a value: " + optionalText1.get()); } else { System.out.println("optionalText1 is empty (no value present)."); } System.out.println("\nChecking optionalText2 (from empty string):"); if (optionalText2.isPresent()) { System.out.println("optionalText2 contains a value: " + optionalText2.get()); } else { System.out.println("optionalText2 is empty (no value present)."); } System.out.println("\nChecking optionalText3 (from non-empty string):"); if (optionalText3.isPresent()) { System.out.println("optionalText3 contains a value: " + optionalText3.get()); } else { System.out.println("optionalText3 is empty (no value present)."); } // Using orElse() to provide a default value if the Optional is empty String valueOrDefault1 = optionalText1.orElse("Default Value 1"); String valueOrDefault2 = optionalText2.orElse("Default Value 2"); String valueOrDefault3 = optionalText3.orElse("Default Value 3"); System.out.println("\nUsing orElse():"); System.out.println("Value from optionalText1: " + valueOrDefault1); System.out.println("Value from optionalText2: " + valueOrDefault2); System.out.println("Value from optionalText3: " + valueOrDefault3); } }让我们来分析一下新的部分:
import java.util.Optional;:我们需要导入Optional类。Optional.ofNullable(text);:这是从可能为null的变量创建Optional的推荐方法。如果text为null,则创建一个空的Optional;如果text不为null,则创建一个包含text值的Optional。optionalText.isPresent():如果Optional包含非null值,此方法返回true,否则返回false。这是在尝试访问值之前安全检查值是否存在的方法。optionalText.get():此方法返回Optional中包含的值。使用此方法时要谨慎! 如果Optional为空(即isPresent()为false),调用get()会抛出NoSuchElementException。通常最好使用其他Optional方法,如orElse()、orElseGet()或ifPresent()。optionalText.orElse("Default Value"):如果Optional中存在值,此方法返回该值;如果Optional为空,则返回指定的默认值。这是一种安全且方便的提供备用值的方法。
保存文件(Ctrl+S 或 Cmd+S)。
编译程序:
javac HelloJava.java运行程序:
java HelloJava你应该会看到类似以下的输出:
Checking optionalText1 (from null): optionalText1 is empty (no value present). Checking optionalText2 (from empty string): optionalText2 contains a value: Checking optionalText3 (from non-empty string): optionalText3 contains a value: Hello Using orElse(): Value from optionalText1: Default Value 1 Value from optionalText2: Value from optionalText3: Hello注意,
optionalText1(从null创建)被正确识别为空。optionalText2(从空字符串""创建)在Optional的概念中 并非 为空,因为它包含一个有效的String对象(即使该字符串为空)。optionalText3包含 "Hello" 字符串。orElse()的示例展示了在Optional为空时如何轻松提供默认值。
在处理可能缺失的值时,使用 Optional 可以使你的代码更健壮、更具表现力。它促使你考虑值缺失的可能性并显式处理,从而降低意外出现 NullPointerException 的几率。
总结
在本次实验中,我们学习了在 Java 中使用相等运算符 (==) 检查变量(特别是 ArrayList)是否为 null 的基本方法。我们了解到,null 表示对象引用的缺失,尝试使用 null 变量可能会导致 NullPointerException。我们通过一个简单的 Java 程序练习了这种基本的空值检查。
我们还探索了更可靠的技术来处理潜在的空值和空集合。这包括结合空值和空集合检查,以确保同时考虑这两种情况;以及使用 Optional 类,以更现代、更安全的方式处理可能缺失的值,从而使代码更具可读性且更不易出错。



