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 直接寫入的 |