杰瑞科技汇

Java如何转为Unicode编码?

  1. 转义序列:在字符串中,用 \uXXXX 的形式表示一个字符,XXXX 是该字符的 4 位或 8 位十六进制 Unicode 码点,这是 Java 源代码中直接书写 Unicode 字符的方式。
  2. 码点表示:直接显示字符的十进制或十六进制码点值,U+4E2D 表示“中”字。

下面我将详细介绍如何在 Java 中实现这两种转换,并提供清晰的代码示例。


转换为 Unicode 转义序列 (\uXXXX)

这是最常见的需求,通常用于在代码中生成包含特殊字符的字符串,或者在日志、配置文件中安全地显示非 ASCII 字符。

核心思路

遍历字符串中的每一个字符,获取其 Unicode 码点,然后将该码点格式化为 \u 后跟 4 位或 8 位十六进制数的形式。

代码实现

这里提供一个健壮的工具方法,它可以正确处理所有 Unicode 字符,包括那些需要 8 位(代理对,Surrogate Pair)表示的字符(如 Emoji)。

import java.util.Locale;
public class UnicodeConverter {
    /**
     * 将字符串转换为 Unicode 转义序列形式。
     * 将 "你好" 转换为 "\u4F60\u597D"。
     *
     * @param str 要转换的字符串
     * @return 转换后的 Unicode 字符串
     */
    public static String stringToUnicodeEscapes(String str) {
        if (str == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            // 对于基本多文种平面 (BMP) 中的字符,码点 <= 0xFFFF
            if (ch < 0x10000) {
                sb.append(String.format("\\u%04X", (int) ch));
            } 
            // 对于辅助平面 (Supplementary Planes) 中的字符,需要使用代理对
            // Emoji 表情符号,码点 > 0xFFFF
            else {
                // 将码点分解为高位和低位代理
                int codePoint = str.codePointAt(i);
                sb.append(String.format("\\u%04X\\u%04X", 
                        Character.highSurrogate(codePoint),
                        Character.lowSurrogate(codePoint)));
                // 因为 codePointAt 会消耗两个 char,所以这里 i 需要额外增加
                i++; 
            }
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        // 示例 1: 常见的中文字符
        String chineseStr = "你好,世界!Hello World!";
        System.out.println("原始字符串: " + chineseStr);
        System.out.println("Unicode 转义: " + stringToUnicodeEscapes(chineseStr));
        // 输出: \u4F60\u597D\uFF0C\u4E16\u754C\uFF01Hello World!
        System.out.println("--------------------");
        // 示例 2: Emoji (位于辅助平面,需要8位表示)
        String emojiStr = "😊 Java";
        System.out.println("原始字符串: " + emojiStr);
        System.out.println("Unicode 转义: " + stringToUnicodeEscapes(emojiStr));
        // 输出: \uD83D\uDE00 Java
        // 😊 的码点是 U+1F60D,其高位代理是 \uD83D,低位代理是 \uDE00
        System.out.println("--------------------");
        // 示例 3: 空字符串
        String emptyStr = "";
        System.out.println("原始字符串: " + emptyStr);
        System.out.println("Unicode 转义: " + stringToUnicodeEscapes(emptyStr));
        // 输出: (空字符串)
    }
}

代码解释:

  1. StringBuilder: 用于高效地构建最终的字符串。
  2. str.charAt(i): 获取字符串中指定索引的 char
  3. ch < 0x10000: 判断字符是否在基本多文种平面,大部分常用字符(包括中文、拉丁字母等)都在这个平面。
  4. String.format("\\u%04X", (int) ch):
    • %04X: 将整数格式化为 4 位、大写的十六进制数,不足4位前面补零。
    • \\u: \\ 是一个反斜杠的转义,所以最终会输出 \u
  5. str.codePointAt(i): 对于 BMP 之外的字符(如 Emoji),char 无法完整表示一个字符,需要 int 类型的码点,这个方法可以直接获取从位置 i 开始的完整字符的码点。
  6. Character.highSurrogate(codePoint)Character.lowSurrogate(codePoint): 将一个辅助平面的码点分解成两个 char(高位和低位代理)。
  7. i++: 由于 codePointAt 读取了两个 char 的位置,所以循环变量 i 需要额外自增一次,以跳过下一个 char

显示字符的 Unicode 码点 (如 U+4E2D)

这种方法不生成 \uXXXX 转义序列,而是直接显示每个字符对应的 Unicode 码点值,常用于调试或分析字符串内容。

核心思路

遍历字符串,对每个字符使用 Character.codePointAt() 获取其码点,然后格式化输出。

代码实现

import java.util.Locale;
public class UnicodeCodePointViewer {
    /**
     * 将字符串的每个字符及其 Unicode 码点打印出来。
     *
     * @param str 要分析的字符串
     */
    public static void printCodePoints(String str) {
        if (str == null) {
            System.out.println("字符串为 null");
            return;
        }
        System.out.println("字符串: \"" + str + "\"");
        System.out.println("字符码点分析:");
        for (int i = 0; i < str.length(); ) {
            int codePoint = str.codePointAt(i);
            // 获取字符的 Unicode 表示 (如 U+4E2D)
            String hexCodePoint = String.format("U+%04X", codePoint).toUpperCase(Locale.ROOT);
            // 获取字符本身
            char[] chars = Character.toChars(codePoint);
            String character = new String(chars);
            System.out.printf("字符: '%s' -> 码点: %s (十进制: %d)%n", character, hexCodePoint, codePoint);
            // 移动到下一个字符
            i += Character.charCount(codePoint);
        }
    }
    public static void main(String[] args) {
        String testStr = "A中😊";
        printCodePoints(testStr);
    }
}

输出结果:

字符串: "A中😊"
字符码点分析:
字符: 'A' -> 码点: U+0041 (十进制: 65)
字符: '中' -> 码点: U+4E2D (十进制: 20013)
字符: '😊' -> 码点: U+1F60D (十进制: 128521)

代码解释:

  1. str.codePointAt(i): 获取从位置 i 开始的完整字符的码点。
  2. Character.charCount(codePoint): 这是一个关键方法,它返回表示给定码点所需的 char 数量,对于 BMP 字符,返回 1;对于辅助平面字符,返回 2,这确保了我们能正确地遍历整个字符串,尤其是在处理 Emoji 时。
  3. i += Character.charCount(codePoint): 根据当前字符占用的 char 数量来更新索引 i,确保循环不会出错。
  4. Character.toChars(codePoint): 将一个码点转换为一个或两个 char 组成的数组,然后可以用来重建原始字符。

需求 方法 关键技术 适用场景
转为 \uXXXX 转义序列 stringToUnicodeEscapes() String.format, Character.highSurrogate/lowSurrogate, codePointAt 在源代码、JSON、XML 中安全地表示非ASCII字符;生成特定格式的字符串。
显示字符的码点 printCodePoints() codePointAt, Character.charCount, Character.toChars 调试、日志分析、理解字符串的内部编码结构。

选择哪种方法取决于你的具体目标,如果你想在 Java 程序中生成一个包含特殊字符的字符串字面量,使用方法一,如果你想查看或分析字符串中每个字符的编码信息,使用方法二

分享:
扫描分享到社交APP
上一篇
下一篇