You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中生僻汉字处理后变为乱码(?)的问题排查与修复咨询

Java生僻汉字「𡍼」乱码问题解析

在Java中处理生僻汉字「𡍼」时,出现字符变为?的乱码情况,测试代码及输出如下:

测试代码

public static void main(String[] args) throws UnsupportedEncodingException {
    String a1 = "𡍼";
    System.out.println(a1 + ".charAt(0)=" + (a1.charAt(0) + 0));
    StringBuffer a = new StringBuffer();
    a.append("a=C0000002006人力資源處").append(a1.charAt(0));
    PrintStream out = new PrintStream(System.out, true, "UTF-8");
    out.println(a);
    System.out.println(a.toString());
    StringBuffer b = new StringBuffer();
    b.append("b=C0000002006人力資源處").append(a1.substring(0,1));
    out.println(b);
    System.out.println(b.toString());
}

执行输出

𡍼.charAt(0)=55364
a=C0000002006人力資源處?
a=C0000002006人力資源處?
b=C0000002006人力資源處?
b=C0000002006人力資源處?

原因分析

这不是Java的Bug,核心原因是「𡍼」属于Unicode辅助平面字符(代码点U+2137C),而Java的char类型是基于UTF-16编码的16位字符单元,辅助平面字符需要用**两个连续的char(代理对)**来表示:

  • a1.charAt(0)仅获取了代理对中的第一个高代理字符(值为55364,对应U+D844),这个单独的代理字符没有实际语义,无法被正确解析显示,因此输出为?。
  • a1.substring(0,1)同样只截取了第一个代理字符,导致相同的乱码问题。

修复方案

要正确处理这类辅助平面字符,需要基于Unicode代码点而非16位char单元来操作,以下是几种可行的修复方式:

  • 直接截取完整字符范围
    由于「𡍼」占2个char单元,直接截取substring(0,2)即可获取完整字符:
StringBuffer b = new StringBuffer();
b.append("b=C0000002006人力資源處").append(a1.substring(0,2));
  • 通过代码点转换为完整字符串
    使用codePointAt获取完整代码点,再转换为char数组后拼接:
int codePoint = a1.codePointAt(0);
char[] chars = Character.toChars(codePoint);
StringBuffer a = new StringBuffer();
a.append("a=C0000002006人力資源處").append(chars);
  • 遍历字符串的代码点
    如果需要批量处理包含多个辅助平面字符的字符串,推荐使用codePoints()方法遍历:
StringBuilder sb = new StringBuilder();
sb.append("c=C0000002006人力資源處");
a1.codePoints().forEach(cp -> sb.append(Character.toChars(cp)));

修复后的输出示例

𡍼.charAt(0)=55364
a=C0000002006人力資源處𡍼
a=C0000002006人力資源處𡍼
b=C0000002006人力資源處𡍼
b=C0000002006人力資源處𡍼

内容的提问来源于stack exchange,提问作者Albert_you

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:20:11