char
不是 Java 中的 2 字节(16 位)吗?
为什么用 UTF-8 编码写入时,一个中文要占 3 个字节?
✅ 一、Java 中的 char
是什么?
- Java 的
char
是一个 固定大小的 2 字节(16 位)类型,表示一个 UTF-16 编码单元; - 它的范围是 0 ~ 65535,能直接表示所有的 基本多语言平面字符(BMP),即 U+0000 ~ U+FFFF。
所以你在内存中看到的:
char[] chars = {'H', 'i', '你', '好'};
这个 char[]
在内存中确实占了 8 字节(4 × 2 字节)。
✅ 二、UTF-8 是一种“变长”的字符编码
- UTF-8 是一种用于 文件/网络传输时的字节编码格式;
- 它不是固定 2 字节,而是变长编码:
字符范围(Unicode) | 编码长度(UTF-8) |
---|---|
U+0000 ~ U+007F | 1 字节(ASCII) |
U+0080 ~ U+07FF | 2 字节 |
U+0800 ~ U+FFFF | 3 字节 |
U+10000 ~ U+10FFFF | 4 字节(需要两个 char 表示) |
✅ 三、中文字符“你好”占多少字节?
中文字符“你”和“好”的 Unicode 编码是:
字符 | Unicode | UTF-8 编码(十六进制) | UTF-8 字节数 |
---|---|---|---|
你 | U+4F60 | E4 BD A0 | 3 字节 |
好 | U+597D | E5 A5 BD | 3 字节 |
✅ 四、为什么 UTF-8 编码比 Java 内存中的 char
多?
编码位置 | 数据内容 | 编码方式 | 字节数 |
---|---|---|---|
Java 内存 | char[] | UTF-16,每个 char 占 2 字节 | 8 字节(H i 你 好) |
写入文件 | Writer → UTF-8 编码 | ASCII 占 1 字节,中文占 3 字节 | 总共 8 字节(1+1+3+3) |
你写入时用了 Writer + UTF-8 编码,这是“把 UTF-16 字符 转换为 UTF-8 字节流”的过程。
✅ 五、简单类比图示:
Java char[] (UTF-16): [H][i][你][好]
字节数(内存中): 2 2 2 2 = 8字节UTF-8 编码写入文件: H→1字节 i→1字节 你→3字节 好→3字节 = 8字节
你看到的文件占 8 字节,刚好是:
- H(1)
- i(1)
- 你(3)
- 好(3)
✅ 结论总结
问题 | 回答 |
---|---|
Java 的 char 是 2 字节吗? | ✅ 是的,UTF-16 编码单元 |
UTF-8 中一个中文是几字节? | 通常是 3 字节(U+0800 ~ U+FFFF 范围) |
为什么 UTF-8 比 char 更长? | 因为 UTF-8 是变长编码,针对不同字符长度不同 |
最终文件内容是字节编码还是字符? | 是 UTF-8 编码的 字节数据,不是 Java 的 char 直接写入的 |