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

为什么UTF-8中3字节特殊字符仅让字符串总长度增加1?

问题根因分析

  • 你混淆了两个完全独立的概念:编码后字节数组的长度和Java String.length()的返回值
    你计算的15+3=18是「字符串用UTF-8编码后的总字节数」,这个计算本身是对的:15个ASCII字符每个在UTF-8下占1字节,特殊字符ࢤ(Unicode码点U+08A4,属于阿拉伯语补充区块)是BMP平面字符,UTF-8编码占3字节,总字节数确实是18字节。
  • Java的String.length()返回的从来不是字节数,而是字符串包含的UTF-16代码单元数量。所有码点在U+0000~U+FFFF(即BMP基本多文种平面)内的字符,每个都只占用1个UTF-16代码单元,因此length()返回值等于字符串的字符总数。你测试的原字符串一共是15个普通ASCII字符加1个ࢤ,总共16个字符,只要字符串内容没有损坏,length()必然返回16。
  • 你写的测试代码本身存在逻辑错误:new String("xxx".getBytes(指定编码))这种写法会产生乱码。你用指定编码把字符串转为字节数组后,调用new String(byte[])时会用JVM的默认编码去解码字节数组,如果默认编码和你转字节用的编码不一致,就会直接生成乱码字符串。你打印出来的16、32、64其实是乱码后的字符串的长度,完全不是你预想的对应编码的字节长度。

正确的测试写法

如果你要统计不同编码下的字节长度,应该直接统计getBytes()返回的字节数组的长度,不要转成String再统计:

public class TestEncoding {
    public static void main(String[] args) throws Exception {
        String str = "Hi how are you?ࢤ";
        System.out.println("UTF-8 字节数:" + str.getBytes("UTF-8").length);
        System.out.println("UTF-16LE 字节数:" + str.getBytes("UTF-16LE").length);
        System.out.println("UTF-32 字节数:" + str.getBytes("UTF-32").length);
    }
}

运行后输出结果就会符合你的预期:

UTF-8 字节数:18
UTF-16LE 字节数:32
UTF-32 字节数:64

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:42:02