这是一个非常经典且容易混淆的问题,因为 split() 方法的行为会根据你传入的正则表达式和的不同而产生巨大差异。

核心要点
split()方法接受的是正则表达式,而不仅仅是普通的字符串,这意味着 , , , , 等字符在split()中有特殊的含义。- 空字符串 作为一个正则表达式,其含义是“匹配任意两个字符之间的位置”,也就是“零宽断言”。
使用 String.split("") 分割一个非空字符串
这是最常见的情况,也是最容易产生误解的地方。
行为:
当你对一个非空字符串使用 split("") 时,它会将字符串的每一个字符都分割开,并且在开头和结尾也插入一个空的分割结果。
示例代码:
public class SplitEmptyString {
public static void main(String[] args) {
String text = "Java";
// 使用 "" 作为分割正则表达式
String[] parts = text.split("");
System.out.println("原始字符串: \"" + text + "\"");
System.out.println("分割后的数组长度: " + parts.length);
System.out.println("分割结果: " + Arrays.toString(parts));
}
}
输出结果:

原始字符串: "Java"
分割后的数组长度: 5
分割结果: [, J, a, v, a]
解释:
- 第一个元素 是在字符串开头(位置 0)之前分割产生的。
J,a,v,a是每个字符本身。- 最后一个元素 是在字符串末尾(位置 4)之后分割产生的。
split("") 会将字符串拆分成单个字符的数组,并在首尾各增加一个空字符串。
使用 String.split("") 分割一个空字符串
这是你问题的核心,当一个空字符串被 split("") 处理时,情况会变得有些特殊。
行为:
根据 Java 的规范,"".split("") 的结果是 [""](一个只包含一个空字符串的数组)。

示例代码:
public class SplitEmptyStringOnEmpty {
public static void main(String[] args) {
String text = "";
String[] parts = text.split("");
System.out.println("原始字符串: \"" + text + "\"");
System.out.println("分割后的数组长度: " + parts.length);
System.out.println("分割结果: " + Arrays.toString(parts));
}
}
输出结果:
原始字符串: ""
分割后的数组长度: 1
分割结果: [""]
解释:
这个结果看起来可能有点反直觉,想象一下,空字符串 没有任何字符。split("") 正则试图在字符之间分割,但由于没有字符,也就没有“之间”的位置,它不会产生任何新的分割点,它只返回原始的、未被分割的空字符串本身。
使用 String.split(" ")(空格)分割一个字符串
这个场景是为了对比,因为很多人会把 split("") 和 split(" ") 混淆。
行为: 是一个普通的空格字符,不是特殊的正则表达式,它会按照字面意思,在每一个空格字符处进行分割。
示例代码:
public class SplitSpaceString {
public static void main(String[] args) {
String text1 = "Hello World";
String text2 = " Hello World "; // 多个连续空格
System.out.println("--- 示例 1: \"Hello World\" ---");
String[] parts1 = text1.split(" ");
System.out.println("分割结果: " + Arrays.toString(parts1)); // [Hello, World]
System.out.println("\n--- 示例 2: \" Hello World \" ---");
String[] parts2 = text2.split(" ");
System.out.println("分割结果: " + Arrays.toString(parts2)); // [, , Hello, , , , World, ,]
}
}
输出结果:
--- 示例 1: "Hello World" ---
分割结果: [Hello, World]
--- 示例 2: " Hello World " ---
分割结果: [, , Hello, , , , World, ,]
解释:
- 在
text1中,只有一个空格,所以被分割成两个部分。 - 在
text2中,连续的空格也会产生连续的分割点,开头的两个空格会在第一个字符前产生两个分割,因此得到两个空字符串 作为结果的开头,结尾的两个空格同理。
String.split() 不带任何参数
这是一个特例,行为非常明确。
行为:
当 split() 方法不带任何参数时,它会使用默认的正则表达式 \\s+(一个或多个空白字符,包括空格、制表符、换行符等)进行分割,并且会忽略结果开头和结尾的空白。
示例代码:
public class SplitWithNoArgument {
public static void main(String[] args) {
String text = " Hello World \t from Java\n";
String[] parts = text.split(""); // 注意:这里是无参调用
System.out.println("原始字符串: \"" + text + "\"");
System.out.println("分割后的数组长度: " + parts.length);
System.out.println("分割结果: " + Arrays.toString(parts));
}
}
输出结果:
原始字符串: " Hello World from Java
"
分割后的数组长度: 4
分割结果: [Hello, World, from, Java]
解释:
split()自动处理了字符串开头和结尾的所有空白字符。- 它将连续的空白字符(多个空格、一个制表符
\t、一个换行符\n)视为一个分割点。
总结与最佳实践
| 方法调用 | 示例字符串 | 结果 | 解释 |
|---|---|---|---|
split("") |
"Java" |
[, J, a, v, a] |
按每个字符分割,并在首尾添加空字符串。 |
split("") |
[""] |
空字符串无法被分割,返回其本身。 | |
split(" ") |
"a b" |
["a", "b"] |
按单个空格字符分割。 |
split(" ") |
"a b" |
["a", "", "b"] |
连续的空格会产生空的分割结果。 |
split(" ") |
" a b " |
["", "a", "b", ""] |
开头和结尾的空格也会产生空的分割结果。 |
split() (无参) |
" a b " |
["a", "b"] |
按一个或多个空白字符分割,并自动去除首尾空白。 |
如何正确地按字符分割并避免首尾的空字符串?
如果你只想得到 ["J", "a", "v", "a"] 这样的结果,可以这样做:
String text = "Java";
// 1. 先用 split("") 分割
String[] parts = text.split("");
// 2. 使用 Arrays.copyOfRange 截取掉首尾的空元素
// Arrays.copyOfRange 的参数是 [fromIndex, toIndex)
String[] chars = Arrays.copyOfRange(parts, 1, parts.length - 1);
System.out.println(Arrays.toString(chars)); // 输出: [J, a, v, a]
如何分割并忽略连续分隔符产生的空字符串?
如果你有一个 "a,,b" 这样的字符串,想得到 ["a", "b"](忽略中间的空字符串),可以使用 split 的第二个参数 limit。
当 limit 为 0 时,方法会丢弃结果末尾的空字符串。
String csv = "a,,b,c,,";
// 使用正则表达式 "," 作为分隔符
// limit=0 表示丢弃末尾的空字符串
String[] result = csv.split(",", 0);
System.out.println(Arrays.toString(result)); // 输出: [a, , b, c]
注意: split(",") 只会丢弃末尾的空字符串,要丢弃所有空字符串,需要使用更复杂的正则表达式,split(",+") (按一个或多个逗号分割)。
String csv2 = "a,,b,c,,";
// 使用 + 量词,表示匹配一个或多个逗号
String[] result2 = csv2.split(",+");
System.out.println(Arrays.toString(result2)); // 输出: [a, b, c]
注意: split(",+") 可能会在开头产生空字符串,如果字符串以分隔符开头。
希望这个详细的解释能帮助你完全理解 Java 中 split() 方法与空字符串相关的各种行为!
