Java中字串所佔的位元組數和字元編碼密切相關。
Java編碼實際上可以涉及這幾個方面的知識:IDE的編碼,作業系統預設編碼,Java字元編碼。
例如:我們使用eclipse編寫Java程式時,可以在工程屬性中設定Java程式的編碼,若不設定,則程式的編碼預設是作業系統的編碼,這裡設定的編碼即為代碼檔案的編碼;或者我們使用vim編寫Java程式時,可以設定系統的環境變數LANG,例如 zh_CN.UTF-8,zh_CN.GB18030等,此時,代碼檔案的編碼就是LANG所指定的編碼。這就是IDE的編碼,IDE的編碼很重要,例如一個Java代碼檔案是UTF-8編碼的,而你的IDE是GB18030編碼,則顯示就會出現亂碼了。
Java中字元的編碼是指Java中的字串所採取的編碼,例如有下面一段程式,用於計算字串所佔位元組數,運行在Windows 7上:
public class Charset { public static void main(String[] args) { // TODO Auto-generated method stub String msg = "中國abc"; System.out.println(msg); int len = msg.getBytes().length;//按作業系統預設編碼來編碼 System.out.println(len); try{ len = msg.getBytes("GB2312").length;//輸出7 System.out.println("GB2312: "+len); len = msg.getBytes("GBK").length;//輸出7 System.out.println("GBK: "+len); len = msg.getBytes("GB18030").length;//輸出7, 2*2+3,一個漢字佔2位元組,一個英文字母一個位元組 System.out.println("GB18030: "+len); len = msg.getBytes("UTF-8").length;//輸出9, 2*3+3=9,一個漢字佔3位元組,一個英文字母一個位元組. System.out.println("UTF-8: "+len); len = msg.getBytes("UTF-16").length;//輸出12 System.out.println("UTF-16: "+len); len = msg.getBytes("UTF-32").length;//輸出20 System.out.println("UTF-32: "+len); len = msg.getBytes("Unicode").length;//輸出12 System.out.println("Unicode: "+len); } catch ( java.io.UnsupportedEncodingException e) { System.out.println(e.getMessage().toString()); } }}
程式輸出是:
中國abc
7
GB2312: 7
GBK: 7
GB18030: 7
UTF-8: 9
UTF-16: 12
UTF-32: 20
Unicode: 12
分析:
len = msg.getBytes().length 的值是7,這是因為Windows 7作業系統字元編碼是GBK(GB2312或GBK或GB18030),Java在運行程式時以作業系統預設編碼來編碼字元,所以字元所佔位元組數是7。
若該段程式放在,
[zhankunlin@IctHTC javatest]$ export LANG=zh_CN.GB18030[zhankunlin@IctHTC javatest]$ vim Charset.java (編寫Java代碼檔案時,使用的編碼是zh_CN.GB18030,即代碼檔案中的編碼是 GB18030)[zhankunlin@IctHTC javatest]$ javac Charset.java [zhankunlin@IctHTC javatest]$ java Charset (LANG=zh_CN.GB18030,即系統預設編碼是GB18030)中國abc7 (系統預設編碼是GB18030,所以佔7個位元組) GB2312: 7GBK: 7GB18030: 7UTF-8: 9UTF-16: 12UTF-32: 20Unicode: 12[zhankunlin@IctHTC javatest]$ export LANG=zh_CN.UTF-8 (更改系統編碼為 UTF-8 )[zhankunlin@IctHTC javatest]$ java Charset涓..abc (由於XShell終端編碼沒有設定成 UTF-8,所以列印出現亂碼)9 (作業系統編碼是UTF-8,所以佔9個位元組)GB2312: 7GBK: 7GB18030: 7UTF-8: 9UTF-16: 12UTF-32: 20Unicode: 12
{設定XShell終端編碼為 utf-8 }
[zhankunlin@IctHTC javatest]$ java Charset中國abc (列印正常)9GB2312: 7GBK: 7GB18030: 7UTF-8: 9UTF-16: 12UTF-32: 20Unicode: 12[zhankunlin@IctHTC javatest]$ vim Charset.java
[zhankunlin@IctHTC javatest]$ javac Charset.java (程式碼檔案編碼是 GB18030,而編譯時間系統編碼是 UTF-8,編譯器編譯時間若沒有任何指定就會以作業系統編碼的方式去讀取代碼檔案進行編譯,所以出現警告)Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎 String msg = "錕叫癸拷abc"; ^Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎 String msg = "錕叫癸拷abc";
[zhankunlin@IctHTC javatest]$ javac -encoding gb18030 Charset.java (使用 -encoding 選項指定程式檔案的編碼格式,則編譯不會出問題)[zhankunlin@IctHTC javatest]$ java Charset {列印正常,因為XShell終端編碼已經設定為了 utf-8 }}中國abc9GB2312: 7GBK: 7GB18030: 7UTF-8: 9UTF-16: 12UTF-32: 20Unicode: 12