用java String類的getBytes(String charsetName)和String(byte[] bytes, String charsetName)解決亂碼問題

Java中String的數據是如何存儲的,查看源代碼就能夠知道,String的數據是存儲在char[] value這樣一個成員變量中的,char類型的大小在java中是2個字節 
咱們還知道,如今廣泛使用的unicode版本是UCS-2,就是使用2個字節表示一個字符的unicode版本,這就對上了,java使用的就是UCS-2標準,因此,String中的value中存儲的都是一個個數字
java

好比’你’的unicode編碼是4f60,看下面的測試代碼web

char c = '你'; System.out.println(Integer.toHexString(c)); System.out.println(Integer.valueOf(c)); System.out.println(c);

結果是: 
4f60 
20320 
數組

因此呢,如今咱們知道了String內部其實存儲的是未經任何編碼的unicode編碼,就是那個對應字符的編碼,而後再看咱們這兩個方法:瀏覽器

getBytes(charsetname) 
意思是根據這個編碼來獲取字節數組 
這又是什麼意思呢? 
就是說將內存中的unicode編碼轉換爲charsetname格式所對應的字節數組 
好比’你’,轉換爲utf-8是三個字接,因此獲得的字節數組就是三個字節的 
即[e4 bd a0]
測試

而後String(bytes,charsetname)呢編碼

意思就是將bytes這個字節數組按照charsetname解釋,組裝爲一個String保存起來 
例如上面那個字節數組[e4 bd a0],按照utf-8解釋的話,存儲起來就是」你」這個字符串,若是按照其餘編碼解釋,則不會解釋爲」你」
spa

說個其餘的,爲何在servlet中處理參數通常都須要這麼一句了來控制編碼:code

String str = new String(param.getBytes(「ISO-8859-1」),」UTF-8」);內存

其實這很好理解,瀏覽器傳過來的字節數據是UTF-8編碼的,而後web容器默認這個字節數據是ISO-8859-1編碼的,因此使用ISO-8859-1把這個字節數據轉換變成了String存儲起來,至關因而進行了下面這個操做:utf-8

String s = new String(UTF8Bytes,」ISO-8859-1」);

注意這個編碼是單字節的,也就是將每個字節都轉換成了unicode編碼,幸虧是這樣,使咱們有機會將這個String再轉換成和原來如出一轍的字節數組,因此纔有了咱們平時用的最多的那一句編碼處理的代碼

最後,想再說一下,對編碼這塊不瞭解的緣由,是咱們理解錯誤,咱們必須知道的是:

java內部存儲字符串使用的unicode編碼 
咱們一般會聽到有人說:「我須要將String由ISO-8859-1轉換爲GBK編碼」,這又是怎麼回事呢?實際上,咱們並非要「將 一個由ISO-8859-1編碼的String轉換爲GBK編碼的String」,反覆說明的是,JAVA中的String都是unicode編碼的,因此不存在「ISO- 8859-1編碼的String」或「GBK編碼的String」這樣的說法。而須要轉換的惟一的緣由是String進行了錯誤的編碼。咱們常常會碰到由ISO-8859- 1轉換爲諸如GBK/UTF-8等等這樣的需求。所謂的轉換過程是:String –> byte[] –>String

相關文章
相關標籤/搜索