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上:
[java] view plaincopy
- 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());
- }
- }
- }
[java] view plain copy
- 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。
若該段程序放在,
[plain] view plaincopy
- [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)
- 中國abc
- 7 (系統默認編碼是GB18030,所以佔7個字節)
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 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: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
[plain] view plain copy
- [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)
- 中國abc
- 7 (系統默認編碼是GB18030,所以佔7個字節)
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 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: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
[plain] view plaincopy
- {設置XShell終端編碼爲 utf-8 }
[plain] view plain copy
- {設置XShell終端編碼爲 utf-8 }
[plain] view plaincopy
- [zhankunlin@IctHTC javatest]$ java Charset
- 中國abc (打印正常)
- 9
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
- [zhankunlin@IctHTC javatest]$ vim Charset.java
[plain] view plain copy
- [zhankunlin@IctHTC javatest]$ java Charset
- 中國abc (打印正常)
- 9
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
- [zhankunlin@IctHTC javatest]$ vim Charset.java
[plain] view plaincopy
- [zhankunlin@IctHTC javatest]$ javac Charset.java (程序代碼文件編碼是 GB18030,而編譯時系統編碼是 UTF-8,編譯器編譯時若沒有任何指定就會以操作系統編碼的方式去讀取代碼文件進行編譯,所以出現警告)
- Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎
- String msg = "錕叫癸拷abc";
- ^
- Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎
- String msg = "錕叫癸拷abc";
[plain] view plain copy
- [zhankunlin@IctHTC javatest]$ javac Charset.java (程序代碼文件編碼是 GB18030,而編譯時系統編碼是 UTF-8,編譯器編譯時若沒有任何指定就會以操作系統編碼的方式去讀取代碼文件進行編譯,所以出現警告)
- Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎
- String msg = "錕叫癸拷abc";
- ^
- Charset.java:6: 璀?.錛.??.UTF8 ?.??..灝..絎
- String msg = "錕叫癸拷abc";
[plain] view plaincopy
- [zhankunlin@IctHTC javatest]$ javac -encoding gb18030 Charset.java (使用 -encoding 選項指定程序文件的編碼格式,則編譯不會出問題)
- [zhankunlin@IctHTC javatest]$ java Charset {打印正常,因爲XShell終端編碼已經設置爲了 utf-8 }}
- 中國abc
- 9
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
[plain] view plain copy
- [zhankunlin@IctHTC javatest]$ javac -encoding gb18030 Charset.java (使用 -encoding 選項指定程序文件的編碼格式,則編譯不會出問題)
- [zhankunlin@IctHTC javatest]$ java Charset {打印正常,因爲XShell終端編碼已經設置爲了 utf-8 }}
- 中國abc
- 9
- GB2312: 7
- GBK: 7
- GB18030: 7
- UTF-8: 9
- UTF-16: 12
- UTF-32: 20
- Unicode: 12
[plain] view plaincopy
- <pre>
[plain] view plain copy
- <pre>
[plain] view plaincopy
- </pre><pre name="code" class="plain">
[plain] view plain copy
- </pre><pre name="code" class="plain">
[plain] view plaincopy
- </pre><pre name="code" class="plain">
[plain] view plain copy
- </pre><pre name="code" class="plain">
[plain] view plaincopy
- </pre><pre name="code" class="plain"><pre>