核心概念
首先要明确一点:在 Java 的 String 类型中,Unicode 字符和汉字是同一种东西。\u4e2d\u6587 这种形式是 Java 源代码层面的一种字面量表示法,当 Java 编译器读取源代码时,会自动将其编译成内部的 UTF-16 编码的字符。

(图片来源网络,侵删)
我们的任务不是在运行时进行“转换”,而是解析一个包含 \uxxxx 形式子串的普通字符串,并将这些子串替换成它们所代表的实际字符。
使用 String 的 replace() 方法(最推荐、最简单)
这是最直接、最简洁的方法,思路是:
- 定义一个正则表达式,用来匹配所有
\u开头、后面跟着4个十六进制数字的模式。 - 使用
String.replaceAll()方法,将所有匹配到的模式替换成对应的字符。
示例代码
public class UnicodeConverter {
public static void main(String[] args) {
// 1. 准备一个包含 Unicode 转义序列的字符串
String unicodeString = "\\u4e2d\\u6587\\u6d4b\\u8bd5"; // 注意:在 Java 字符串中,反斜杠需要转义,所以是 "\\u"
// 2. 定义正则表达式来匹配 \uXXXX 格式
// \\u : 匹配字面量 "\u" (第一个反斜杠是转义符)
// [0-9a-fA-F] : 匹配一个十六进制数字 (0-9, a-f, A-F)
// {4} : 前面的字符组恰好出现4次
String regex = "\\\\u[0-9a-fA-F]{4}";
// 3. 使用 replaceAll 进行替换
// 第一个参数是正则表达式,第二个参数是一个替换函数。
// 我们使用一个 lambda 表达式 (Matcher::quoteReplacement) 来处理匹配到的字符串。
// 这里我们不需要复杂的处理,可以直接用 String 的构造函数。
// 一个更清晰的写法是:
String result = unicodeString.replaceAll(regex, matcher -> {
// matcher.group(0) 获取到完整的匹配字符串,"\u4e2d"
String unicodeChar = matcher.group(0);
// 直接返回这个 Unicode 字符串本身,因为 Java 会自动将其解释为字符
return unicodeChar;
});
// 上面的 lambda 可以简化为更经典的写法,利用 Unicode 字符串字面量的特性:
// String result = unicodeString.replaceAll(regex, m -> m.group(0));
// 或者,如果你想显式地转换,可以这样:
/*
String result = unicodeString.replaceAll(regex, m -> {
String code = m.group(0).substring(2); // 去掉 "\u"
int hexValue = Integer.parseInt(code, 16); // 将十六进制字符串转为 int
return String.valueOf((char) hexValue); // 将 int 强转为 char,再转为 String
});
*/
System.out.println("原始字符串: " + unicodeString);
System.out.println("转换后字符串: " + result); // 输出: 转换后字符串: 中文测试
}
}
代码解释:
unicodeString = "\\u4e2d\\u6587\\u6d4b\\u8bd5";- 在 Java 字符串中,反斜杠
\是一个转义字符,要在字符串中表示一个字面量的\u,你必须写成\\u。
- 在 Java 字符串中,反斜杠
regex = "\\\\u[0-9a-fA-F]{4}";- 这是一个正则表达式。
\\\\匹配一个\字符,[0-9a-fA-F]匹配一个十六进制数字,{4}表示前面这个模式重复4次。
- 这是一个正则表达式。
unicodeString.replaceAll(regex, ...)replaceAll会找到所有匹配regex的子串,并用第二个参数(一个替换函数)返回的值进行替换。- 在我们的 lambda
m -> m.group(0)中,m.group(0)获取的是匹配到的完整字符串,\u4e2d,当这个字符串被作为返回值放回String中时,Java 会自动将其解释为对应的汉字“中”,这是最巧妙也最简单的方式。
使用 Pattern 和 Matcher(更灵活)
这种方法与方法一原理完全相同,只是不使用 String 内置的 replaceAll,而是显式地创建 Pattern 和 Matcher 对象,这在需要更精细控制匹配过程时非常有用。

(图片来源网络,侵删)
示例代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UnicodeConverterWithPattern {
public static void main(String[] args) {
String unicodeString = "\\u4e2d\\u56fd\\u4eba\\u6c11";
String regex = "\\\\u[0-9a-fA-F]{4}";
// 1. 编译正则表达式
Pattern pattern = Pattern.compile(regex);
// 2. 创建匹配器
Matcher matcher = pattern.matcher(unicodeString);
// 3. 使用 StringBuffer 来存储结果
StringBuffer result = new StringBuffer();
// 4. 循环查找并替换
while (matcher.find()) {
// 获取匹配到的 Unicode 字符串,"\u4e2d"
String unicodeChar = matcher.group();
// 替换逻辑:直接 append 匹配到的字符串本身
matcher.appendReplacement(result, unicodeChar);
}
// 5. 将剩余部分添加到结果中
matcher.appendTail(result);
System.out.println("原始字符串: " + unicodeString);
System.out.println("转换后字符串: " + result.toString()); // 输出: 转换后字符串: 中国人民
}
}
代码解释:
Pattern.compile(regex): 将正则表达式字符串编译成一个Pattern对象,可以提高重复使用的效率。matcher.find(): 尝试在输入字符串中查找下一个匹配项。matcher.appendReplacement(result, replacement): 这是一个非常强大的方法,它将上次匹配结束之后到本次匹配开始之前的文本,以及替换文本,追加到StringBuffer中,然后它会更新匹配器的位置,以便进行下一次查找。matcher.appendTail(result): 当find()返回false后,调用此方法将输入字符串中剩余的部分追加到StringBuffer中。
手动解析(不依赖正则表达式)
如果你不想使用正则表达式,或者想了解底层原理,可以手动实现一个解析器。
示例代码
public class UnicodeConverterManual {
public static void main(String[] args) {
String unicodeString = "\\u4e2d\\u6587";
StringBuilder result = new StringBuilder();
for (int i = 0; i < unicodeString.length(); i++) {
char c = unicodeString.charAt(i);
// 如果当前字符是反斜杠,并且后面跟着 'u',并且后面还有至少4个字符
if (c == '\\' && i + 1 < unicodeString.length() && unicodeString.charAt(i + 1) == 'u' && i + 5 < unicodeString.length()) {
// 提取4位十六进制字符
String hexStr = unicodeString.substring(i + 2, i + 6);
try {
// 将十六进制字符串转换为整数
int codePoint = Integer.parseInt(hexStr, 16);
// 将整数转换为字符并添加到结果中
result.append((char) codePoint);
// 跳过已经处理的 \uXXXX 部分
i += 5;
} catch (NumberFormatException e) {
// 如果不是有效的十六进制,就当作普通字符处理
result.append(c);
}
} else {
// 如果不是 Unicode 序列,直接添加字符
result.append(c);
}
}
System.out.println("原始字符串: " + unicodeString);
System.out.println("转换后字符串: " + result.toString()); // 输出: 转换后字符串: 中文
}
}
代码解释:
- 我们遍历字符串的每一个字符。
- 当我们检测到
\u序列时,我们手动截取后面的4个字符。 - 使用
Integer.parseInt(hexStr, 16)将十六进制字符串(如 "4e2d")转换为一个整数(codePoint)。 - 使用
(char) codePoint将这个整数强制转换为char类型,这恰好就是对应的汉字。 - 将转换后的字符添加到
StringBuilder中,并调整索引i以跳过已处理的\uXXXX部分。
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
String.replaceAll() |
代码简洁,一行搞定,可读性高 | 依赖正则表达式,性能可能略低于手动循环(但通常可以忽略) | 绝大多数情况下的首选,简单高效。 |
Pattern 和 Matcher |
功能强大,灵活,可进行复杂的匹配和替换逻辑 | 代码稍多,比 replaceAll 冗长 |
需要在匹配过程中进行复杂处理,或需要重用 Pattern 对象时。 |
| 手动解析 | 不依赖正则表达式,性能理论上最高 | 代码复杂,容易出错(如边界条件处理) | 对性能有极致要求,或者环境不支持正则表达式等特殊场景。 |
对于绝大多数 Java 方法一 (String.replaceAll() + Lambda) 是最值得推荐的,因为它在代码简洁性和功能之间取得了完美的平衡。

(图片来源网络,侵删)
