JAVA总结(三):sun.jnu.encoding与file.encoding的区别

先说结论,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

所以在本机运行的所有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();
    }

}

按照上述结论的话,那么在系统中产生的文件名应该是中文乱码才对,但经过多次测试,文件名依旧显示正常,所以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());
    }

}

如果此文件作为主函数运行,输出的结果为GBK,但其作为服务被UTF-8的JAVA类调用时,则输出UTF-8,很有意思吧!

继续测试,如果在第一个类里(UTF-8编码)也声明常量ENCODE_STR,并取值为”国际米兰”,这时我们利用winhex查看class的字节码文件,我们可以发现国际米兰都被翻译成了相同的二进制,如下:

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

经过演算,我们可以算出国际米兰的UTF-8编码正是上述字节。

结论

无论JAVA文件(文本)采用什么编码,转换为class时,都会转为UTF-8编码。

你可能感兴趣的:(java)