解析Class文件出现乱码的原因分析-CoffeeLover-搜狐博客

来源:百度文库 编辑:神马文学网 时间:2024/04/30 01:31:52

解析Class文件出现乱码的原因分析

标签: 文件  源文件  编码  编译器  解析  2006-10-26 20:34

现象:我们在编译源文件EncodingTest.java时,编译通过;但用java EncodigngTest解析EncdoingTest.class文件时,总是显示乱码.

EncodingTest.java内容如下:

public class EncodingTest

{

    public static void main(String args[])

    {

        System.out.println("A中国A");

    }

}

执行javac EncodingTest后显示如下:

理论上,应该是输出 “A中国A”,那为什么会出现乱码呢?

我们来看看从java源文件到解析生成class文件,这一过程发生了什么事情,如下图:

 

(1)            当我们执行javac命令时,如果没有指明encoding参数,编译器就会把源文件当作GB2312编码格式的文件编译成为UTF-8编码的class文件。

(2)            当我们执行java命令的时候,JVM把class文件的UTF-8字符转化为UNICODE格式的编码字符加载进内存中.

显然,解析class文件出现乱码的源头就是在编译的时候.把上面的EncodingTest.java用记事本打开,点击“文件”>>“另存为”,可以看到下图: 

所以原因就在于:我们的源文件的编码格式为UTF-8,编译器默认地把它当作GB2312的编码格式编译成class文件,必然会出现乱码!

我们把上面的源文件记事本打开,“文件”>“另存为”然后直接按保存(备份源文件),再执行javac EncodingTest.java,发现编译报错,奇怪为什么同样是一个UTF-8编码的源文件,我们没有作过任何修改,那为什么第一次执行通过,而第二次执行会报错呢?

用16进制编辑软件打开,发现我们第二次保存的源文件多了“EF BB BF”文件头,所以原因很明显:

        当我们用javac编译第一个源文件时,由于没有文件头,所以可以把编译器骗过去;但第二次保存的那个文件,由于多了UTF-8的文件头,当编译器用默认的GB2132来编译源文件时,发现文件头是UTF-8的文件头就认为我们是在骗它,所以彻底让编译不通过!

       那么是不是我们指明编译时源文件的编码,编译就可以通过且正确解析呢?用第二次保存的文件,我们执行javac –encoding UTF-8 EncodingTest.java,发现编译不通过;把文件头删去,再执行上面命令,发现编码和解析都正常进行,由此得知编译器只认识没有文件头的UTF-8编码格式文件!

      由分析可知,如果一个java源文件通过,但解析显示出错,那么极大可能是编译时编码转化出了问题!