简介
在这个实验中,你将学习 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 编程中是非常常见的模式。
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
的值,通过明确指出值可能缺失,让代码更健壮、更具可读性。