







































































































【1】在中文平臺(tái)下,測試的結(jié)果如下:
System default encoding --- GBK
System default language --- zh
Get characters with default encoding
char[0]='中' byte=45 \u2D short=20013 \u4E2D CJK_UNIFIED_IDEOGRAPHS
char[1]='文' byte=-121 \uFFFFFF87 short=25991 \u6587 CJK_UNIFIED_IDEOGRAPHS
Characters length: 2
Get characters with given encoding : ISO-8859-1
char[0]='?' byte=-42 \uFFFFFFD6 short=214 \uD6 LATIN_1_SUPPLEMENT
char[1]='?' byte=-48 \uFFFFFFD0 short=208 \uD0 LATIN_1_SUPPLEMENT
char[2]='?' byte=-50 \uFFFFFFCE short=206 \uCE LATIN_1_SUPPLEMENT
char[3]='?' byte=-60 \uFFFFFFC4 short=196 \uC4 LATIN_1_SUPPLEMENT
Characters length: 4
Get characters with given encoding : GBK
char[0]='中' byte=45 \u2D short=20013 \u4E2D CJK_UNIFIED_IDEOGRAPHS
char[1]='文' byte=-121 \uFFFFFF87 short=25991 \u6587 CJK_UNIFIED_IDEOGRAPHS
Characters length: 2
Get characters with given encoding : UTF-8
char[0]='?' byte=-3 \uFFFFFFFD short=-3 \uFFFFFFFD SPECIALS
char[1]='?' byte=-3 \uFFFFFFFD short=-3 \uFFFFFFFD SPECIALS
char[2]='?' byte=-3 \uFFFFFFFD short=-3 \uFFFFFFFD SPECIALS
char[3]='?' byte=-3 \uFFFFFFFD short=-3 \uFFFFFFFD SPECIALS
Characters length: 4
【2】在英文平臺(tái)下,測試的結(jié)果如下:
System default encoding --- Cp1252
System default language --- en
Get characters with default encoding
char[0]='?' byte=45 \u2D short=20013 \u4E2D CJK_UNIFIED_IDEOGRAPHS
char[1]='?' byte=-121 \uFFFFFF87 short=25991 \u6587 CJK_UNIFIED_IDEOGRAPHS
Characters length: 2
Get characters with given encoding : ISO-8859-1
char[0]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
char[1]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
Characters length: 2
Get characters with given encoding : GBK
char[0]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
char[1]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
Characters length: 2
Get characters with given encoding : UTF-8
char[0]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
char[1]='?' byte=63 \u3F short=63 \u3F BASIC_LATIN
Characters length: 2
【結(jié)論】
和getBytes(encoding)不同,toCharArray()返回的是"自然字符"。但是這個(gè)"自然字符"的數(shù)目和內(nèi)容卻是由原始的編碼方式?jīng)Q定的。來看看里面是如何進(jìn)行字符串的操作的:
String encodedString = new String(content.getBytes(), encoding);
char[] charArray = inStr.toCharArray();
可以看到系統(tǒng)首先對原始字符串按照默認(rèn)的編碼方式進(jìn)行編碼,得到一個(gè)字節(jié)數(shù)組,然后按照指定的新的編碼方式進(jìn)行解碼,得到新的編碼后的字符串。再轉(zhuǎn)換成對應(yīng)的字符數(shù)組。
由于在中文平臺(tái)下,默認(rèn)的字符集編碼是GBK,于是content.getBytes()得到的是什么呢?就是下面這4個(gè)字節(jié):
byte[0] = -42 hex string = ffffffd6
byte[1] = -48 hex string = ffffffd0
byte[2] = -50 hex string = ffffffce
byte[3] = -60 hex string = ffffffc4
如果新的encoding是GBK,那么經(jīng)過解碼后,由于一個(gè)字符用2個(gè)字節(jié)表示。于是最終的結(jié)果就是:
char[0]='中' --- byte[0] + byte[1]
char[1]='文' --- byte[2] + byte[3]
如果新的encoding是ISO-8859-1,那么經(jīng)過解碼后,由于一個(gè)字符用1個(gè)字節(jié)表示,于是原來本應(yīng)該2個(gè)字節(jié)一起解析的變成單個(gè)字節(jié)解析,每個(gè)字節(jié)都代表了一個(gè)漢字字符的一半。這一半的字節(jié)在ISO-8859-1中找不到對應(yīng)的字符,就變成了"?"了,最終的結(jié)果:
char[0]='?' ---- byte[0]
char[1]='?' ---- byte[1]
char[2]='?' ---- byte[2]
char[3]='?' ---- byte[3]
如果新的encoding是UTF-8,那么經(jīng)過解碼后,由于一個(gè)字符用3個(gè)字節(jié)表示,于是原來4個(gè)字節(jié)的數(shù)據(jù)無法正常的解析成UTF-8的數(shù)據(jù),最終的結(jié)果也是每一個(gè)都變成"?"。
char[0]='?' ---- byte[0]
char[1]='?' ---- byte[1]
char[2]='?' ---- byte[2]
char[3]='?' ---- byte[3]
如果是在英文平臺(tái)下,由于默認(rèn)的編碼方式是Cp1252,于是content.getBytes()得到的字節(jié)都是被截去一半的殘留字符,所以我們看到在英文平臺(tái)下,不論指定的encoding是GBK、UTF-8,其結(jié)果和ISO-8859-1都是一樣的。
記住:
這個(gè)方法再次證明了String的getBytes()方法的危險(xiǎn)性,如果我們使用new String(str.getBytes(), encoding)對字符串進(jìn)行重新編碼解碼時(shí),我們一定要清楚str.getBytes()方法返回的字節(jié)數(shù)組的長度、內(nèi)容到底是什么,因?yàn)樵诮酉聛硎褂眯碌膃ncoding進(jìn)行編碼解碼時(shí),Java并不會(huì)自動(dòng)地對字節(jié)數(shù)組進(jìn)行擴(kuò)展以適應(yīng)新的encoding。而是按照新的編碼方法直接對該字節(jié)數(shù)組進(jìn)行解析。
于是結(jié)果就像上面的例子一樣,同樣是4個(gè)原始字節(jié),有些每2個(gè)一組進(jìn)行解析,有些每個(gè)一組進(jìn)行解析,有些每3個(gè)一組進(jìn)行解析。其結(jié)果就只能看那種編碼方式合適了。
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。