之所以是兩個字節(jié),是因為Java內(nèi)部使用UTF-16編碼,所以char為了表示BMP中的字符,所以占了兩個字節(jié)。很明顯,不能表示所有字符。
Unicode是一種字符集規(guī)范,而且還在不斷發(fā)展之中。我們常說的UTF-8,UTF-16編碼是其不同的兩種實現(xiàn)。請注意,字符集和編碼不是一回事。Unicode規(guī)范好比就是定義了每個字符對應(yīng)一個數(shù)字,至于如何把這個數(shù)字存放在計算機中,那是另一回事。Unicode收錄的每個字符對應(yīng)一個數(shù)字,稱作碼點(code point),通常用“U+”后面跟著一個十六進制數(shù)表示。
其實UTF-16比UTF-8更早出現(xiàn),在UTF-16之前還存在UCS-2,該編碼固定使用16位編碼,后來發(fā)現(xiàn)16位根本不夠使用,IEEE曾推薦過UCS-4,即固定使用4個字節(jié)編碼,但因為太過浪費空間被Unicode拒絕采納了。此時,UTF-16就出現(xiàn)了。Unicode將16位的字符集做了延申,并規(guī)定每216為一個plane, 第一個plane稱作 Basic Multilingual Plane(簡稱 BMP), 這里面的字符使用兩個字節(jié)。對于超出了第一個plane的其他字符,將被收錄在其他層級的plane,并使用第一層的代理(surrogate)將其表示,占用四個字節(jié)。至于怎么表示以及怎么編碼解碼的,請移步維基百科,有詳細的解釋。
JVM內(nèi)部使用的是UTF-16編碼。不管代碼文件中char使用的是什么編碼,都將被JVM轉(zhuǎn)化為UTF-16而且只用兩個字節(jié),也就是說Java中的char占用兩個字節(jié),只能表示Unicode中第一層(BMP)中的字符,對于其他字符會報錯:Invalid Character Constant, 而String中是可以的。
ASCII 碼
學(xué)過計算機的人都知道 ASCII 碼,總共有 128 個,用一個字節(jié)的低 7 位表示,0~31 是控制字符如換行回車刪除等;32~126 是打印字符,可以通過鍵盤輸入并且能夠顯示出來。ISO-8859-1
128 個字符顯然是不夠用的,于是 ISO 組織在 ASCII 碼基礎(chǔ)上又制定了一些列標(biāo)準(zhǔn)用來擴展 ASCII 編碼,它們是 ISO-8859-1~ISO-8859-15,其中 ISO-8859-1 涵蓋了大多數(shù)西歐語言字符,所有應(yīng)用的最廣泛。ISO-8859-1 仍然是單字節(jié)編碼,它總共能表示 256 個字符。GB2312
它的全稱是《信息交換用漢字編碼字符集 基本集》,它是雙字節(jié)編碼,總的編碼范圍是 A1-F7,其中從 A1-A9 是符號區(qū),總共包含 682 個符號,從 B0-F7 是漢字區(qū),包含 6763 個漢字。GBK
全稱叫《漢字內(nèi)碼擴展規(guī)范》,是國家技術(shù)監(jiān)督局為 windows95 所制定的新的漢字內(nèi)碼規(guī)范,它的出現(xiàn)是為了擴展 GB2312,加入更多的漢字,它的編碼范圍是 8140~FEFE(去掉 XX7F)總共有 23940 個碼位,它能表示 21003 個漢字,它的編碼是和 GB2312 兼容的,也就是說用 GB2312 編碼的漢字可以用 GBK 來解碼,并且不會有亂碼。GB18030
全稱是《信息交換用漢字編碼字符集》,是我國的強制標(biāo)準(zhǔn),它可能是單字節(jié)、雙字節(jié)或者四字節(jié)編碼,它的編碼與 GB2312 編碼兼容,這個雖然是國家標(biāo)準(zhǔn),但是實際應(yīng)用系統(tǒng)中使用的并不廣泛。UTF-16
說到 UTF 必須要提到 Unicode(Universal Code 統(tǒng)一碼),ISO 試圖想創(chuàng)建一個全新的超語言字典,世界上所有的語言都可以通過這本字典來相互翻譯。可想而知這個字典是多么的復(fù)雜,關(guān)于 Unicode 的詳細規(guī)范可以參考相應(yīng)文檔。Unicode 是 Java 和 XML 的基礎(chǔ),下面詳細介紹 Unicode 在計算機中的存儲形式。
UTF-16 具體定義了 Unicode 字符在計算機中存取方法。UTF-16 用兩個字節(jié)來表示 Unicode 轉(zhuǎn)化格式,這個是定長的表示方法,不論什么字符都可以用兩個字節(jié)表示,兩個字節(jié)是 16 個 bit,所以叫 UTF-16。UTF-16 表示字符非常方便,每兩個字節(jié)表示一個字符,這個在字符串操作時就大大簡化了操作,這也是 Java 以 UTF-16 作為內(nèi)存的字符存儲格式的一個很重要的原因。
- UTF-8
UTF-16 統(tǒng)一采用兩個字節(jié)表示一個字符,雖然在表示上非常簡單方便,但是也有其缺點,有很大一部分字符用一個字節(jié)就可以表示的現(xiàn)在要兩個字節(jié)表示,存儲空間放大了一倍,在現(xiàn)在的網(wǎng)絡(luò)帶寬還非常有限的今天,這樣會增大網(wǎng)絡(luò)傳輸?shù)牧髁?,而且也沒必要。而 UTF-8 采用了一種變長技術(shù),每個編碼區(qū)域有不同的字碼長度。不同類型的字符可以是由 1~6 個字節(jié)組成。
UTF-8 有以下編碼規(guī)則:
如果一個字節(jié),最高位(第 8 位)為 0,表示這是一個 ASCII 字符(00 - 7F)。可見,所有 ASCII 編碼已經(jīng)是 UTF-8 了。
如果一個字節(jié),以 11 開頭,連續(xù)的 1 的個數(shù)暗示這個字符的字節(jié)數(shù),例如:110xxxxx 代表它是雙字節(jié) UTF-8 字符的首字節(jié)。
如果一個字節(jié),以 10 開始,表示它不是首字節(jié),需要向前查找才能得到當(dāng)前字符的首字節(jié)
————————————————
版權(quán)聲明:本文為CSDN博主「harrisonlee.net」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/LZCDTU/article/details/103865748