在討論這個問題之前,我們需要先區分unicode和UTF。 1. unicode :統一的字元編號,僅僅提供字元與編號間映射。符號數量在不斷增加,已超百萬。詳細:[https://zh.wikipedia.org/zh cn/Unicode] 1. UTF :unicode轉換格式 (unicode ...
在討論這個問題之前,我們需要先區分unicode和UTF。
- unicode :統一的字元編號,僅僅提供字元與編號間映射。符號數量在不斷增加,已超百萬。詳細:[https://zh.wikipedia.org/zh-cn/Unicode]
- UTF :unicode轉換格式 (unicode transformation format) 。定義unicode中編號的編碼方式。utf8和utf16便是其中兩種實現方式。其中utf8為變長表示,長度可能時1~6個位元組;utf16為變長表示,長度可能是2或4個位元組。詳細:UTF8 [https://zh.wikipedia.org/zh-cn/UTF-8] UTF16 [https://zh.wikipedia.org/zh-cn/UTF-16]
接著,要分清內碼(internal encoding)和外碼(external encoding)。
- 內碼 :某種語言運行時,其char和string在記憶體中的編碼方式。
- 外碼 :除了內碼,皆是外碼。
要註意的是,源代碼編譯產生的目標代碼文件(可執行文件或class文件)中的編碼方式屬於外碼。
先看一下內碼
JVM中內碼採用UTF16。早期,UTF16採用固定長度2位元組的方式編碼,兩個位元組可以表示65536種符號(其實真正能表示要比這個少),足以表示當時unicode中所有字元。但是隨著unicode中字元的增加,2個位元組無法表示所有的字元,UTF16採用了2位元組或4位元組的方式來完成編碼。Java為應對這種情況,考慮到向前相容的要求,Java用一對char來表示那些需要4位元組的字元。所以,java中的char是占用兩個位元組,只不過有些字元需要兩個char來表示。
詳細:
[https://docs.oracle.com/javase/tutorial/i18n/text/unicode.html][http://www.zhihu.com/question/27562173]
外碼
Java的class文件採用UTF8來存儲字元,也就是說,class中字元占1~6個位元組。
Java序列化時,字元也採用UTF8編碼,占1~6個字元。
總結:
- java中內碼(運行記憶體)中的char使用UTF16的方式編碼,一個char占用兩個位元組,但是某些字元需要兩個char來表示。所以,一個字元會占用2個或4個位元組。
- java中外碼中char使用UTF8的方式編碼,一個字元占用1~6個位元組。
- UTF16編碼中,英文字元占兩個位元組;絕大多數漢字(尤其是常用漢字)占用兩個位元組,個別漢字(在後期加入unicode編碼的漢字,一般是極少用到的生僻字)占用四個位元組。
- UTF8編碼中,英文字元占用一個位元組;絕大多數漢字占用三個位元組,個別漢字占用四個位元組。
EOF