天天看點

關于String的getBytes(),getBytes(encoding)和new String(bytes, encoding)這三個方法的學習總結

關于String的getBytes(),getBytes(encoding)和new String(bytes, encoding)這三個方法,非常值得注意:

A.getBytes():使用平台預設的編碼方式(通過file.encoding屬性擷取)方式來将字元串轉換成byte[]。得到的是字元串最原始的位元組編碼值。

B.getBytes(NAME_OF_CHARSET):使用指定的編碼方式将字元串轉換成byte[],如果想要得到正确的位元組數組,程式員必須給出正确的NAME_OF_CHARSET。否則得到的就不會得到正确的結果。

C.new String(bytes, encoding):如果我們在用戶端使用UTF-8編碼的JSP頁面送出請求,浏覽器編碼後的UTF-8位元組會以ISO-8859-1的形式傳遞到伺服器端。是以要得到經HTTP協定傳輸的原始位元組,我們需要先調用getBytes("ISO-8859-1")得到原始的位元組,但由于我們用戶端的原始編碼是UTF-8,如果繼續按照ISO-8859-1解碼,那麼得到的将不是一個中文字元,而是3個亂碼的字元。是以我們需要再次調用new String(bytes,"UTF-8"),将位元組數組按照UTF-8的格式,每3個一組進行解碼,才能還原為用戶端的原始字元。

編碼方式:

1、JVM中單個字元占用的位元組長度跟編碼方式有關,而預設編碼方式又跟平台是一一對應的或說平台決定了預設字元編碼方式;

2、對于單個字元:ISO-8859-1單位元組編碼,GBK雙位元組編碼,UTF-8三位元組編碼;是以中文平台(中文平台預設字元集編碼GBK)下一個中文字元占2個位元組,而英文平台(英文平台預設字元集編碼Cp1252(類似于ISO-8859-1))。

3、getBytes()、getBytes(encoding)函數的作用是使用系統預設或者指定的字元集編碼方式,将字元串編碼成位元組數組。

編碼方式決定位元組長度;在中文平台下,預設的字元集編碼是GBK,此時如果使用getBytes()或getBytes("GBK"),則按照GBK的編碼規則将每個中文字元用2個byte表示。是以我們看到"中文"最終GBK編碼結果就是: -42 -48 -50 -60 。-42和-48代表了"中"字,而"-50"和"-60"則代表了"文"字。

在中文平台下,如果指定的字元集編碼是UTF-8,那麼按照UTF-8對中文的編碼規則:每個中文用3個位元組表示,那麼"中文"這兩個字元最終被編碼成:-28 -72 -83、-26 -106 -121兩組。每3個位元組代表一個中文字元。

在中文平台下,如果指定的字元集編碼是ISO-8859-1,由于此字元集是單位元組編碼,是以使用getBytes("ISO-8859-1")時,每個字元隻取一個位元組,每個漢字隻取到了一半的字元。另外一半的位元組丢失了。由于這一半的字元在字元集中找不到對應的字元,是以預設使用編碼63代替,也就是?。

在英文平台下,預設的字元集編碼是Cp1252(類似于ISO-8859-1),如果使用GBK、UTF-8進行編碼,得到的位元組數組依然是正确的(GBK4個位元組,UTF-8是6個位元組)。因為在JVM内部是以Unicode存儲字元串的,使用getBytes(encoding)會讓JVM進行一次Unicode到指定編碼之間的轉換。對于GBK,JVM依然會轉換成4個位元組,對于UTF-8,JVM依然會轉換成6個位元組。但是對于ISO-8859-1,則由于無法轉換(2個位元組--->1個位元組,截取了一半的位元組),是以轉換後的結果是錯誤的。

繼續閱讀