java字元編碼原理淺析__編碼

來源:互聯網
上載者:User

 

本周遇到一個java亂碼問題,於是對java的編碼問題做了一些實驗和瞭解。簡單分析如下:

先看下如下代碼:

import java.io.UnsupportedEncodingException;

public class CharSetTest {

public static void main(String[] args) throws UnsupportedEncodingException {

String test = " 籃球 " ;

byte [] defaultResult = test.getBytes();

for ( byte e : defaultResult) {

System. out .print(e + " " );

}

System. out .println(System. getProperty ( "file.encoding" ));

System. out .println( "test=" + test);

}

}

1.執行 javac CharSetTest.java,能正常編譯,但是得到如下警告:
CharSetTest.java:5: warning: unmappable character for encoding ASCII
        String test = "????";
分析一下為什麼會這樣呢。對於java編譯器來說,CharSetTest.java就是一個文字檔,java編譯器要解析 這個文字檔並編譯產生.class檔案。分析了下原因大概是這樣的:CharSetTest.java一定是以某一種編碼格式來儲存的,所以java編 譯器一定要知道該文字檔時用什麼來編碼的,如果沒有指定就用預設認為檔案的編碼格式是” ANSI_X3.4-1968”(不同環境可能不一樣),所以就會發現無法解釋的中文而出現了亂碼。
那麼以上問題該如何解決,就是要在編譯的時候告訴編譯器,需要編譯的java檔案的編碼格式,否則編譯器有可能遇到不能理解的字元就當做亂碼處理了。由於 CharSetTest.java是GBK格式的,所以通過如下命令完成:
Javac CharSetTest.java –encoding=GBK。

2. 通過執行Javac CharSetTest.java –encoding=GBK,已經能得到正確的class檔案了,但是執行 java  CharSetTest,結果如下:
63 63 ANSI_X3.4-1968
test=??
那麼既然已經正確編譯了,為什麼得到的輸出結果還會是亂碼呢。前面已經可以肯定.class檔案裡面存放的中文字串是正確的了,那原因肯定是在JVM 從.class檔案讀取這個字串位元組流並構建String對象的時候採用了錯誤的字元編碼來構建位元組流。進而導致從JVM輸出字串的位元組流到我們控制 台的時候,出現亂碼。那麼很顯然,我們必須告訴jvm我們控制台的編碼,或者我們希望它採用什麼字元編碼來構建位元組流。如果沒有告訴jvm,那麼檔案的編 碼格式是” ANSI_X3.4-1968”(不同環境可能不一樣)。
 假設我們控制台是GBK的編碼,那麼只要我們正確告訴它,它就能正確的返回位元組流了。那麼原因就比較簡單,我們沒有正確告訴JVM我們需要它構造字串 輸出資料流的時候應該採用的編碼格式。那麼該如何處理呢。通過如下命令:
java -Dfile.encoding=GBK CharSetTest
得到結果:
-64 -70 -57 -14 GBK
test=籃球
以上實驗在eclipse下面並不會成立,因為eclipse會幫我們做一些判斷。同時不同的環境可能也不 一樣。

最後總結:
Java的class檔案採用UTF-8,在JVM裡面採用UTF-16。整個過程中編碼轉換大概可以看下圖:

 

 

 

 

從上圖可以理解不管採用那種格式的源檔案,只要正確告訴編譯器,編譯器就會得到正確的結果。同時只要告訴JVM正確的輸出資料流需要的編碼格式,JVM總會返 回正確編碼格式的輸出資料流。


那麼要想不產生亂碼要注意兩個環節:
1.    告訴編譯器你的源檔案編碼。
2.    告訴jvm你顯示或者構造字串輸出資料流時希望的編碼。
尤其JSP亂碼時要注意request請求採用的編碼和解析request時候採用的編碼是否一致,response的編碼和html charset的編碼是否一致。

同時我們常遇到jsp、資料庫等亂碼問題可以找一下是否是以下兩種原因:
1.    誤解型:a檔案是GBK編碼,但是你以為是UTF-8型編碼,所以用UTF-8來理解它,就會出現亂碼。
2.    無能為力型:a檔案時GBK編碼,你也知道它是GBK編碼,但是你想轉換成ISO-8859-1的方式來顯示,但是GBK裡面有很多字元時ISO- 8859-1所不能解釋的,這時也會出現亂碼。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.