由char和byte的關系引申出去——總結一下java中的字符編碼相關知識
一、字符編碼
手持兩把錕斤拷,口中直呼燙燙燙
? ??在文章伊始,先來復習一下計算機中關于編碼的一些基礎知識,著重理清以下幾個基本概念,
1. 碼點(code point)
? ??計算機只能以二進制的形式存盤文字,故而計算機中每一個字母,文字,符號,emoji都對應著一個二進制數,而這個二進制數就是碼點,
2. 字符集
? ??光有碼點還不夠,我們還得知道有哪些碼點,這些碼點又能表示哪些字符,于是便又到了喜聞樂見的制定標準環節,標準所支持的所有字符及其對應碼點的集合被稱為字符集,例如學過C語言的同學都知道的ASCII字符集,它共包含了128個字符,包括數字,26個字母的大小寫及一些符號,對應的碼點就是0-127,再有就是后面要提到的Unicode字符集,
3. 編碼
? ??以ASCII字符集為例,它的碼點為0-127,最大不超過7bit,而計算機中一般是以8bit的位元組(byte)為單位,出于種種考量,實際存盤在計算機中的碼點的二進制都會在頭部添0,以8bit存盤,例如A對應碼點65,二進制為100 0001,實際在計算機中存盤為0100 0001,這種在計算機中實際存盤的內容到字符的映射就是編碼,
? ??我們熟悉的編碼方式有ASCII,UTF-8,UTF-16,歐洲的ISO,中國大陸的GBK等等,計算機中存盤的同一段二進制,用不同的編碼方式,會得到完全不同的內容,
4. Unicode字符集
? ??ASCII一共只包含了128個字符,顯然不夠用,于是便有了Unicode字符集,Unicode字符集中收錄了世界上絕大多數文字,符號等,反正就是非常多,
? ??行文至此,筆者想到自己當初學習時的一個疑惑,即字符集已經規定好了字符到碼點的映射,為啥還有各種不同的編碼方式,如果讀者仔細理解了上文不難發現,在計算機中以何種方式存盤碼點是需要編碼來確定,最簡單的方法就是直接將碼點轉成二進制存盤,比如對ASCII字符集的ASCII編碼,對Unicode的UTF-32編碼,
? ??由于Unicode字符集數量極其旁大,單個字符最大已超過了3個位元組(具體多大我也不清楚,目前用4個位元組還足夠表示),同時為了區分前后兩個字符在哪里斷開,utf-32編碼簡單粗暴得將每個字符以32位4位元組的形式存盤在計算機中,這樣很好理解,但帶來了嚴重的空間浪費,對于常用的字母得要存一堆0,簡直就是0溢事件,
5. UTF-8編碼
? ??我們常見的utf-8便是為了解決上述問題而誕生的,他是針對于Unicode的可變長度編碼方式,可以把不同字符以1,2,3,4位元組大小存盤到計算機中,同時utf-8兼容ascii,具體規則參考下圖,也推薦大家看一下圖片下方鏈接的視頻,講的很好:

圖片來源:【你懂亂碼嗎?錕斤拷燙燙燙(詳解ASCII、Unicode、UTF-32、UTF-8編碼)】 https://www.bilibili.com/video/BV1xP4y1J7CS/?share_source=copy_web&vd_source=f5db843fce15b7c3e2990f4f7a6e8921
二、Java中的字符編碼
1. 編碼方式:
? ??有了以上知識的鋪墊,其實接下來的問題就很好解決了,
? ??首先,java中采用的是基于Unicode字符集的UTF-16編碼方式,utf-16可以將不同字符以2或4位元組大小存盤在計算機中,可能有同學已經發現規律了,utf-8是以8bit為最小單位,而utf-16是以16 bit為最小單位,而這個最小單位實際上就是所謂的代碼單元(code unit),
2. char型別:
? ??基本型別char型別就是一個16bit的代碼單元,我們日常里常用的字符,如字母,漢字等只需要一個char,而對于一些類似于emoji這樣的碼點值很大的字符,需要兩個char,
? ??java中char型別的字面量用'A'單引號括起來,表示一個字符常量,對于一些特殊字符,如回車,換行,我們要用到轉義字符來表示,如下圖:

3. 應用:
? ??行文至此,筆者又想起之前曾經看到過的一個相關的案例,
? ??簡言之就是需要對資料庫中取出的用戶名做一個截斷,比如某些情況下只需要呈現用戶名的前三個字,而這個系統允許用戶上傳的用戶名中包含emoji表情,
? ??在這種情況下就要注意了,一個emoji字符由兩個char組成,如果簡單得用String.subString()或者String.length是有問題的,因為這些方法都是以char為單位,可能會造成把一個emoji字符只截了一個char出來,從而導致問題,在這里就需要用String的codePoint相關的方法去截取,以碼點為單位,因為一個碼點一定代表一個字符,而一個char則未必,
? ??詳情見該視頻:【Emoji 表情導致線上故障2個小時,老板直接損失10萬,到底是什么問題?| 故障復盤 | 實戰經驗分享】 https://www.bilibili.com/video/BV1MG41177pT/?share_source=copy_web
三、 總結:
? ??如果您堅持看到了這里,那么我想一定已經對于我標題提出的問題的答案了然于胸了,
? ??char和byte的關系,現在看來這倆也沒啥關系嘛,只能說我這個引申不是很合適,本文著重介紹了計算機字符編碼的相關知識,同時也總結了java中有關字符編碼的一些內容,希望能對你有所幫助,
四、 參考資料:
- 【你懂亂碼嗎?錕斤拷燙燙燙(詳解ASCII、Unicode、UTF-32、UTF-8編碼)】 https://www.bilibili.com/video/BV1xP4y1J7CS/?share_source=copy_web&vd_source=f5db843fce15b7c3e2990f4f7a6e8921
- 《java核心技術卷Ⅰ》
鄙人只是一名在讀的軟體工程專業的本科生,正在復習找作業,故而將復習時遇到的一些有意思的東西總結出來,既是加深理解,也是便于日后復習,
鄙人才疏學淺,若文中有謬誤之處,還望諸位不吝斧正,以免誤人子弟,若有同道中人想一同討論學習,也可以聯系我=>[email protected],未經本人同意,請勿轉載!
路漫漫其修遠兮,吾將上下而求索,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/541261.html
標籤:其他
