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

Java如何判断一个字符是否由两个UTF-16码点组成?

判断Java中UTF-16双码点字符的方法

Java里的char类型采用UTF-16编码存储字符,对于Unicode码点超过U+FFFF的增补平面字符,会被拆分成两个char组成的代理对存储。比如你测试的字符𒌍(U+1230D),就被拆成了\uD808(高位代理)和\uDF0D(低位代理),单独打印这两个char时,因为它们本身不是有效的独立Unicode字符,所以会显示乱码。

怎么判断一个char属于代理对?

UTF-16的代理对有明确的数值范围和二进制特征:

  • 高位代理:数值范围是0xD800到0xDBFF,二进制格式为110110xx xxxxxxxx
  • 低位代理:数值范围是0xDC00到0xDFFF,二进制格式为110111xx xxxxxxxx

Java的Character类已经封装好了现成的判断方法,直接调用即可:

  • Character.isHighSurrogate(char c):判断当前char是否是高位代理
  • Character.isLowSurrogate(char c):判断当前char是否是低位代理
  • Character.isSurrogate(char c):判断当前char是否是代理对中的任意一个

示例代码

用这段代码可以正确识别代理对并获取完整码点:

String s = "\uD808\uDF0D";
for (int i = 0; i < s.length(); ) {
    char current = s.charAt(i);
    if (Character.isHighSurrogate(current)) {
        // 找到高位代理,必须和下一个char组合成完整字符
        char low = s.charAt(i + 1);
        int fullCodePoint = Character.toCodePoint(current, low);
        System.out.printf("找到代理对:高位0x%X,低位0x%X,对应完整码点U+%X%n", current, low, fullCodePoint);
        i += 2; // 跳过下一个char,因为已经组合过了
    } else {
        System.out.printf("单码点字符:0x%X%n", current);
        i += 1;
    }
}

UTF-16代理对的编码规则(翻译自相关维基内容)

对于Unicode码点在U+010000到U+10FFFF之间的字符,UTF-16用两个16位单元表示,转换逻辑是:

  1. 把目标码点减去0x10000,得到一个20位的数值(范围是0到0xFFFFF)
  2. 将这个20位数值拆分为高10位和低10位两部分
  3. 高10位加上0xD800,得到高位代理的数值
  4. 低10位加上0xDC00,得到低位代理的数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:36:09