您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)如何在Java中使用String保存字符串,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
Java 中的 Unicode 字符串會按照 Latin1(所有的字符都小于 0xFF 時)或者 UTF16 的編碼格式保存在 String 中,保存為 byte 數(shù)組:
private final byte[] value;
通常所說的 Immutable 都是指 final bytes 在 String 初始化后就不會修改,所有字符串的相關(guān)操作都是不會修改原數(shù)組而是創(chuàng)建新的副本。
但是數(shù)組元素理論上是可以修改的,比如下面通過反射的方式,將字符串常量 abc 修改為 Abc:
public static void main(String[] args) { setFirstValueToA("abc"); String replaced = new String("abc"); System.out.println(replaced); // Abc } private static void setFirstValueToA(String str) { Class<String> stringClass = String.class; try { Field value = stringClass.getDeclaredField("value"); value.setAccessible(true); byte[] bytes = (byte[]) value.get(str); bytes[0] = 0x41; // A } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } }
通過如下代碼測試幾個字符串?dāng)?shù)組:
public static void main(String[] args) { printString("abc"); printString("中文"); printString("abc中文"); printString("abc"); } private static void printString(String str) { System.out.println("======>" + str); // return the UTF-16 char[] size System.out.println("length: " + str.length()); // Use default Encoding (UTF-8) System.out.println("getBytes: " + str.getBytes().length); // Convert UTF-16 char[] to char System.out.println("codePointCount: " + str.codePointCount(0, str.length())); // Get the UTF-16 char[] System.out.println("toCharArray: " + str.toCharArray().length); // The UTF-16 char[] to bytes System.out.println("internal value: " + getStringInternalValueLength(str)); }
結(jié)果如下:
首先解釋下 String 的 value 字段計算方式:
所有字符都小于 0xFF 時,采用 Latin1 Character Encoding 來保存 Unicode code point,也就是每個字符都用一個 byte 來保存。比如“ABC”
上述條件不滿足時,采用 UTF-16 Character Encoding 來保存,也就是每個字符都用 2 個或者 4 個 byte 來保存。
Unicode 是 Coded Character Set,將幾乎所有的人類文字映射到 code point 符號,通常格式為 U+xxxx,xxxx 為 16 進(jìn)制整數(shù),表達(dá)范圍為 U+0000~U+10FFFF。code point 符號是文字的規(guī)范化標(biāo)記,但是實際保存時肯定還是要保存為字節(jié)數(shù)組的。這些不同的保存方式就是 Character Encoding,比如 UTF-8,還有 Java String 內(nèi)部采用的 UTF-16。
UTF-16 是一種將 Unicode code point 表達(dá)成字符數(shù)組的編碼方式,對于 U+0000~U+FFFF,直接按照 2 個字節(jié)保存(細(xì)分的話還有大端字節(jié)序和小端字節(jié)序的區(qū)別);對于 U+10000~U+10FFFF,會先轉(zhuǎn)化為一對 U+D800~U+DFFF 范圍內(nèi)的 code point(surrogate pair),再將這兩個 code point 按照前面的規(guī)則保存。之所以選擇這個范圍,是因為這個 Unicode 區(qū)間還沒有被分配有效的字符,因此可以和前面的規(guī)則區(qū)分。
“中文”這兩個漢字的 Unicode code point 非別為 U+4E2d、U+6587,大于 0xFF,所以保存 byte 長度為 4;"abc中文" 中存在不滿足條件的字符,所以全部用 UTF-16 保存,它們都是 2 個 byte 的,所以長度為 10。
“?” 的 Unicode code point 為 U+1F60A,根據(jù) UTF-16 規(guī)范,U+10000~U+10FFFF 需要轉(zhuǎn)化為 surrogate pair 之后再保存成 byte, 轉(zhuǎn)換后為 U+D83D、U+DE0A,因此 "abc" 的字節(jié)長度為 10。
Java 中 char 的大小為 2 個字節(jié),剛好可以表示一個 U+0000~U+FFFF 的 Unicode 符號。
Latin1 編碼時,char 數(shù)組為 byte 數(shù)組的填充,高字節(jié)為 0;UTF-16 編碼時,相當(dāng)于轉(zhuǎn)化過 surrogate pair 后的 Unicode 編碼數(shù)組,其中 0xD800~0xDFFF 范圍內(nèi)的為 surrogate 字符。
“abc” 時為 Latin1 編碼,所以 char 數(shù)組大小等于 bytes 數(shù)組;“abc中文” 時為 UTF-16 編碼,所以 char 數(shù)組大小等于 bytes 數(shù)組的一半。
toCharArray 方法將轉(zhuǎn)化后的 surrogate pair 也算在內(nèi),因此實際長度可能大于字符長度。而 codePointCount 就能去除 surrogate pair 的影響,返回初始的字符長度,它會將連續(xù)兩個 surrogate pair 只計數(shù)一次。
該方法就是 toCharArray 數(shù)組的長度,受到 surrogate pair 的影響,可能大于字符長度。
String 內(nèi)部是通過 UTF-16 編碼保存的字節(jié)數(shù)組,當(dāng)通過 getBytes 方法返回時,是需要指定 Encoding 的,默認(rèn)采用 UTF-8,因此會將 UTF-16 的字節(jié)數(shù)組轉(zhuǎn)化為 UTF-8 的字節(jié)數(shù)組,每個 Unicode 符號在 UTF-8 編碼后長度為 1~4 字節(jié)。
System.out.println("abc".getBytes(UTF_8).length); // 3 System.out.println("中".getBytes(UTF_8).length); // 3 System.out.println("文".getBytes(UTF_8).length); // 3 System.out.println("".getBytes(UTF_8).length); // 4
Java主要應(yīng)用于:1. web開發(fā);2. Android開發(fā);3. 客戶端開發(fā);4. 網(wǎng)頁開發(fā);5. 企業(yè)級應(yīng)用開發(fā);6. Java大數(shù)據(jù)開發(fā);7.游戲開發(fā)等。
以上就是如何在Java中使用String保存字符串,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。