介绍
在这个实验中,你将学习 Java 中处理空字符串的基本技术。我们将首先探讨使用相等运算符 (==) 检查空值的基本方法,理解为什么这对于防止 NullPointerException 至关重要。
在此基础上,你将学习如何将空值检查与空字符串检查相结合,以有效处理各种字符串状态。最后,我们将介绍 Optional 类,它是一种现代且更安全的处理潜在空值的方法,并展示它如何提高代码的可读性并防止常见错误。
在这个实验中,你将学习 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 编程中是非常常见的模式。
在前面的步骤中,你使用了相等运算符 (==) 以及 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 的值,通过明确指出值可能缺失,让代码更健壮、更具可读性。