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編碼。