查看String的源碼可以發現它以一個char類型的數組保存字元串的,而String.length()方法返回的也是這個char數組的長度. 那麼,這個長度和"字元"長度有什麼關係呢? 在這裡就不得不引入碼點和代碼單元的概念,以下是摘抄至《Java核心技術捲一基礎知識(第十版)》中的定義: "碼點( ...
查看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 = "