1. 程式人生 > >JAVA總結(三):sun.jnu.encoding與file.encoding的區別

JAVA總結(三):sun.jnu.encoding與file.encoding的區別

JAVA總結(三):sun.jnu.encoding與file.encoding的區別

2017年08月10日 19:39:24 蟻方陣 閱讀數:1704 標籤: java編碼位元組碼二進位制class檔案 更多

個人分類: java

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/yiifaa/article/details/77072656

先說結論,sun.jnu.encoding是指作業系統的預設編碼,file.encoding是指JAVA檔案的編碼(請記住,不是class檔案,所有class檔案的編碼都是UTF-8),所以,在同一個作業系統上執行的JAVA應用程式,其sun.jnu.encoding完全相同,而file.encoding即使在同一個JAVA應用程式中,JAVA檔案的編碼也可以不一樣。

在大部分的情況下,sun.jnu.encoding對我們都是透明的。

以Windows為例,利用chcp檢視預設編碼:

chcp
# 輸出936,也就是GBK
  • 1
  • 2

所以在本機執行的所有JAVA程序,sun.jnu.encoding都是GBK。

有人說sun.jnu.encoding用於檔名的編碼,flle.encoding用於檔案內容的編碼,真的正確嗎?看下面的例子:

//  此JAVA檔案用UTF-8進行編碼
public class SunEncodingTest {

    public static void main(String[] args) throws  IOException {
        //  輸出結果與檔案編碼一致
        System.out.println(Charset.defaultCharset());
        createFile();
    }

    public static void createFile() throws IOException {
        String fileName = "國際米蘭.txt";
        File file = new File(fileName);
        if(!file.exists()) {
            file.createNewFile();
        }
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
        writer.write(fileName);
        writer.close();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

按照上述結論的話,那麼在系統中產生的檔名應該是中文亂碼才對,但經過多次測試,檔名依舊顯示正常,所以sun.jnu.encoding用於檔名的編碼不是太靠得住的。

繼續看一個有意思的現象,我們再建立一個JAVA檔案,但採用GBK編碼,並在常量中直接寫入中文字元,如下:

public class OsEncode {

    public final static String ENCODE_STR = "國際米蘭";

    public static String encode() {
        return Charset.defaultCharset().name();
    }

    public static void main(String[] args) throws IOException {
        //  輸出結果與檔案編碼一致,GBK
        System.out.println(encode());
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

如果此檔案作為主函式執行,輸出的結果為GBK,但其作為服務被UTF-8的JAVA類呼叫時,則輸出UTF-8,很有意思吧!

繼續測試,如果在第一個類裡(UTF-8編碼)也宣告常量ENCODE_STR,並取值為”國際米蘭”,這時我們利用winhex檢視class的位元組碼檔案,我們可以發現國際米蘭都被翻譯成了相同的二進位制,如下:

E5 9B BD E9 99 85 E7 B1 B3 E5 85 B0
  • 1

經過演算,我們可以算出國際米蘭的UTF-8編碼正是上述位元組。

結論

無論JAVA檔案(文字)採用什麼編碼,轉換為class時,都會轉為UTF-8編碼。