介绍
在这个实验中,你将学习 Java 中处理空字符串的基本技术。我们将首先探讨使用相等运算符 (==) 检查空值的基本方法,理解为什么这对于防止 NullPointerException 至关重要。
在此基础上,你将学习如何将空值检查与空字符串检查相结合,以有效处理各种字符串状态。最后,我们将介绍 Optional 类,它是一种现代且更安全的处理潜在空值的方法,并展示它如何提高代码的可读性并防止常见错误。
使用相等运算符测试空值
在这一步中,你将学习如何使用相等运算符 (==) 来检查 Java 中的字符串变量是否为 null。理解如何处理 null 在 Java 编程中至关重要,可避免出现错误。
在 Java 中,引用类型(如 String)的变量可以持有一个名为 null 的特殊值。这意味着该变量不指向内存中的任何对象。若将 null 变量当作有效对象使用,会导致 NullPointerException,这是初学者常见且头疼的错误。
检查字符串是否为 null 最简单的方法是使用相等运算符 (==)。
下面我们创建一个简单的 Java 程序来演示这一点。
打开 WebIDE,确保你处于
~/project目录下。你可以通过查看终端提示符或输入pwd并按回车键来确认。在
~/project目录下创建一个名为NullCheck.java的新 Java 文件。你可以在左侧的文件资源管理器中右键单击,选择“新建文件”,然后输入NullCheck.java。在编辑器中打开
NullCheck.java文件,并粘贴以下代码:public class NullCheck { public static void main(String[] args) { String myString1 = "Hello"; String myString2 = null; String myString3 = ""; // This is an empty string, not null System.out.println("Checking myString1:"); if (myString1 == null) { System.out.println("myString1 is null"); } else { System.out.println("myString1 is not null"); } System.out.println("\nChecking myString2:"); if (myString2 == null) { System.out.println("myString2 is null"); } else { System.out.println("myString2 is not null"); } System.out.println("\nChecking myString3:"); if (myString3 == null) { System.out.println("myString3 is null"); } else { System.out.println("myString3 is not null"); } } }在这段代码中:
- 我们声明了三个
String变量:myString1被赋值为一个普通字符串,myString2被显式赋值为null,myString3被赋值为空字符串 ("")。 - 我们使用
if语句和相等运算符 (==) 来检查每个字符串是否为null。 - 我们打印一条消息,表明该字符串是否为
null。
- 我们声明了三个
保存
NullCheck.java文件(Ctrl+S 或 Cmd+S)。打开 WebIDE 底部的终端。确保你处于
~/project目录下。使用
javac命令编译 Java 程序:javac NullCheck.java如果没有错误,该命令将在同一目录下创建一个
NullCheck.class文件。使用
java命令运行编译后的 Java 程序:java NullCheck你应该会看到类似以下的输出:
Checking myString1: myString1 is not null Checking myString2: myString2 is null Checking myString3: myString3 is not null
此输出确认了 myString1 和 myString3 不为 null,而 myString2 为 null。需要注意 null 字符串和空字符串 ("") 之间的区别。空字符串是一个有效的 String 对象,只是字符数为零,而 null 字符串变量不指向任何对象。
在 Java 中,使用 == null 是检查引用变量是否为 null 的标准且正确的方法。
结合空值和空字符串检查
在上一步中,你学习了如何检查字符串是否为 null。然而,在许多实际场景中,你可能还需要检查字符串是否为空(字符数为零)或仅包含空白字符。一个为 null、为空或仅包含空白字符的字符串通常被认为是“空白”或“实际上为空”。
同时检查 null 和空字符串是一个常见需求。你可以使用逻辑或运算符 (||) 来结合这些检查。
下面我们修改之前的程序,使其包含对 null 和空字符串的检查。
在 WebIDE 编辑器中打开
NullCheck.java文件。修改
main方法,以包含对空字符串的检查并结合这些检查。将现有的main方法替换为以下代码:public class NullCheck { public static void main(String[] args) { String myString1 = "Hello"; String myString2 = null; String myString3 = ""; // This is an empty string String myString4 = " "; // This string contains only whitespace System.out.println("Checking myString1:"); if (myString1 == null || myString1.isEmpty()) { System.out.println("myString1 is null or empty"); } else { System.out.println("myString1 is not null and not empty"); } System.out.println("\nChecking myString2:"); if (myString2 == null || myString2.isEmpty()) { System.out.println("myString2 is null or empty"); } else { System.out.println("myString2 is not null and not empty"); } System.out.println("\nChecking myString3:"); if (myString3 == null || myString3.isEmpty()) { System.out.println("myString3 is null or empty"); } else { System.out.println("myString3 is not null and not empty"); } System.out.println("\nChecking myString4:"); // Note: isEmpty() does not check for whitespace if (myString4 == null || myString4.isEmpty()) { System.out.println("myString4 is null or empty"); } else { System.out.println("myString4 is not null and not empty"); } } }在这个更新后的代码中:
- 我们添加了
myString4,它仅包含空白字符。 - 我们使用条件
myString == null || myString.isEmpty()来检查字符串是否为null或为空。isEmpty()方法是String类的内置方法,如果字符串长度为 0,则返回true。 - 重要提示:
isEmpty()方法只能在非空字符串上调用。如果你尝试在null字符串上调用isEmpty(),会得到一个NullPointerException。因此,在调用myString.isEmpty()之前,必须先使用myString == null检查是否为null。逻辑或运算符 (||) 是“短路”的,这意味着如果第一个条件 (myString == null) 为真,则不会计算第二个条件 (myString.isEmpty()),从而避免了NullPointerException。
- 我们添加了
保存
NullCheck.java文件。在终端中编译修改后的程序:
javac NullCheck.java运行编译后的程序:
java NullCheck你应该会看到类似以下的输出:
Checking myString1: myString1 is not null and not empty Checking myString2: myString2 is null or empty Checking myString3: myString3 is null or empty Checking myString4: myString4 is not null and not empty
注意,通过这个检查,myString4(仅包含空白字符)被认为是“非 null 且非空”。如果你还需要将仅包含空白字符的字符串视为“空白”,可以使用 isBlank() 方法(Java 11 及以后版本可用)。
下面我们快速更新代码,对 myString4 使用 isBlank() 方法:
修改
NullCheck.java中对myString4的检查:// ... (previous code) ... System.out.println("\nChecking myString4 with isBlank():"); if (myString4 == null || myString4.isBlank()) { System.out.println("myString4 is null or blank"); } else { System.out.println("myString4 is not null and not blank"); } } }保存文件,再次编译并运行:
javac NullCheck.java java NullCheck现在
myString4的输出应该是:Checking myString4 with isBlank(): myString4 is null or blank
这展示了如何结合对 null 和空/空白字符串的检查,这在 Java 编程中是非常常见的模式。
使用 Optional 安全处理空字符串
在前面的步骤中,你使用了相等运算符 (==) 以及 isEmpty() 或 isBlank() 方法来检查 null 和空/空白字符串。虽然这些方法很有效,但 Java 8 引入了 Optional 类,以一种更明确和函数式的方式处理可能为 null 的值。使用 Optional 可以让你的代码更具可读性,并且减少 NullPointerException 的发生。
Optional 是一个容器对象,它可能包含也可能不包含非空值。如果存在值,isPresent() 方法将返回 true,get() 方法将返回该值。如果不存在值,该对象被视为空,isPresent() 方法将返回 false。在空的 Optional 上调用 get() 方法会抛出 NoSuchElementException 异常。
下面我们来探讨如何对字符串使用 Optional。
在 WebIDE 编辑器中打开
NullCheck.java文件。将文件的全部内容替换为以下使用
Optional的代码:import java.util.Optional; public class NullCheck { public static void main(String[] args) { String myString1 = "Hello"; String myString2 = null; String myString3 = ""; String myString4 = " "; // Creating Optional objects from strings Optional<String> optionalString1 = Optional.ofNullable(myString1); Optional<String> optionalString2 = Optional.ofNullable(myString2); Optional<String> optionalString3 = Optional.ofNullable(myString3); Optional<String> optionalString4 = Optional.ofNullable(myString4); System.out.println("Checking optionalString1:"); if (optionalString1.isPresent()) { System.out.println("optionalString1 has a value: " + optionalString1.get()); } else { System.out.println("optionalString1 is empty (contains null)"); } System.out.println("\nChecking optionalString2:"); if (optionalString2.isPresent()) { System.out.println("optionalString2 has a value: " + optionalString2.get()); } else { System.out.println("optionalString2 is empty (contains null)"); } System.out.println("\nChecking optionalString3:"); // Optional.ofNullable("") creates an Optional containing an empty string if (optionalString3.isPresent()) { System.out.println("optionalString3 has a value: " + optionalString3.get()); } else { System.out.println("optionalString3 is empty (contains null)"); } System.out.println("\nChecking optionalString4:"); if (optionalString4.isPresent()) { System.out.println("optionalString4 has a value: " + optionalString4.get()); } else { System.out.println("optionalString4 is empty (contains null)"); } // Using Optional methods for safer handling System.out.println("\nUsing Optional methods:"); // orElse: provides a default value if the Optional is empty String value1 = optionalString1.orElse("Default Value"); String value2 = optionalString2.orElse("Default Value"); System.out.println("Value from optionalString1 (orElse): " + value1); System.out.println("Value from optionalString2 (orElse): " + value2); // ifPresent: performs an action if a value is present System.out.print("If optionalString1 is present: "); optionalString1.ifPresent(s -> System.out.println("Value is " + s)); System.out.print("If optionalString2 is present: "); optionalString2.ifPresent(s -> System.out.println("Value is " + s)); // filter: filters the value if present System.out.print("Filtered optionalString1 (length > 3): "); optionalString1.filter(s -> s.length() > 3).ifPresent(s -> System.out.println("Value is " + s)); System.out.print("Filtered optionalString3 (length > 3): "); optionalString3.filter(s -> s.length() > 3).ifPresent(s -> System.out.println("Value is " + s)); } }在这段代码中:
- 我们导入了
Optional类。 - 我们使用
Optional.ofNullable(string)从普通的String创建一个Optional<String>。即使输入的字符串为null,这个方法也可以安全使用。如果输入为null,它将返回一个空的Optional;否则,它将返回一个包含该字符串的Optional。 - 我们使用
optionalString.isPresent()检查Optional是否包含值。 - 我们使用
optionalString.get()在值存在时获取该值。注意: 在空的Optional上调用get()会抛出异常,所以一定要先检查isPresent()或者使用其他更安全的方法。 - 我们演示了
orElse(defaultValue)方法,如果Optional包含值则返回该值,否则返回指定的默认值。 - 我们演示了
ifPresent(consumer)方法,如果存在值,则执行给定的消费者(一个接受一个参数且不返回结果的函数)。 - 我们演示了
filter(predicate)方法,如果值存在且满足给定的谓词(一个返回布尔值的函数),则返回包含该值的Optional,否则返回一个空的Optional。
- 我们导入了
保存
NullCheck.java文件。在终端中编译程序:
javac NullCheck.java运行程序:
java NullCheck你应该会看到类似以下的输出:
Checking optionalString1: optionalString1 has a value: Hello Checking optionalString2: optionalString2 is empty (contains null) Checking optionalString3: optionalString3 has a value: Checking optionalString4: optionalString4 has a value: Using Optional methods: Value from optionalString1 (orElse): Hello Value from optionalString2 (orElse): Default Value If optionalString1 is present: Value is Hello If optionalString2 is present: Filtered optionalString1 (length > 3): Value is Hello Filtered optionalString3 (length > 3):
使用 Optional 可以让你的代码更清晰地表达一个值是否可能缺失,并且提供了有用的方法来处理值的存在或缺失,而无需在各处进行显式的 null 检查。虽然 Optional 是一个强大的工具,但它并不能替代所有的 null 检查,不过在处理可能为 null 的返回值时特别有用。
总结
在本次实验中,你学习了如何检查 Java 中的字符串是否为 null。首先,你使用相等运算符 (==) 直接将字符串变量与 null 进行比较,了解到 null 表示对象引用的缺失,并且不检查 null 可能会导致 NullPointerException。
接着,你探讨了如何将空值检查与空字符串检查结合起来,认识到空字符串 ("") 是一个有效的对象,这与 null 不同。最后,你学习了如何使用 Java 8 引入的 Optional 类,这是一种更现代、更安全的方式来处理可能为 null 的值,通过明确指出值可能缺失,让代码更健壮、更具可读性。



