String類型的"字符"長度(碼點/代碼單元的區別)


       查看String的源碼可以發現它以一個char類型的數組保存字符串的,而String.length()方法返回的也是這個char數組的長度.

那么,這個長度和"字符"長度有什么關系呢?

       在這里就不得不引入碼點和代碼單元的概念,以下是摘抄至《Java核心技術卷一基礎知識(第十版)》中的定義:

      "碼點( code point ) 是指與一個編碼表中的某個字符對應的代碼值。在Unicode 標准中,碼點采用十六進制書寫,並加上前綴U+, 例如U+0041 就是拉丁字母A 的碼點。Unicode 的碼點可以分成17 個代碼級別( codeplane)。第一個代碼級別稱為基本的多語言級別( basicmultilingual plane ), 碼點從U+0000 到U+FFFF, 其中包括經典的Unicode 代碼;其余的16個級另丨〗碼點從U+10000 到U+10FFFF , 其中包括一些輔助字符(supplementary character)。UTF-16 編碼采用不同長度的編碼表示所有Unicode 碼點。在基本的多語言級別中, 每個字符用16 位表示,通常被稱為代碼單元( code unit ) ; 而輔助字符采用一對連續的代碼單元進行編碼。這樣構成的編碼值落人基本的多語言級別中空閑的2048 字節內, 通常被稱為替代區域(surrogate area) [ U+D800 ~ U+DBFF 用於第一個代碼單兀,U+DC00 ~ U+DFFF 用於第二個代碼單元]。這樣設計十分巧妙, 我們可以從中迅速地知道一個代碼單元是一個字符的編碼, 還是一個輔助字符的第一或第二部分".

     從上面的話可以知道:

           ① 一個字符對應一個碼點(且每個字符的碼點都是唯一的),但一個碼點可能需要一個代碼單元或者兩個代碼單元才能表示。

           ② 一個char類型正好可以保存一個代碼單元的值。也就是說,String類型中的char數組,保存的其實是字符串對應的代碼單元。

由此我們就可以知道String.length()方法返回的是字符串所有代碼單元的數量,而不是字符串中所有字符的個數。(盡管大部分情況下Stirng.length()都等於字符的個數,也就是字符的長度).

比如對於String str = "𝌷",其str.length()的返回結果為2,但它只有一個字符!

將它復制到idea中,你會發現String str = "𝌷"會變為String a = "\uD834\uDF37".

而要想獲取真正的字符長度(字符的個數),我們需要用如下語句:

    str.codePointCount(0,str.length());


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM