java编译器编码和JVM编码问题?

来源:互联网 发布:分析家行情软件 编辑:程序博客网 时间:2024/06/05 00:37


引用网上一张截图,由于网上链接太多,也找不到作者,忘见谅。
一直困惑字符编码里的问题,开门见山,问题:
假设A.java文本文件采用GBK编码,那么javac编译该文件的时候,首先读取该文件,读取后编译成UTF-8编码的字节码文件,这个过程中会导致乱码,这个乱码是不可恢复的,那么为什么在最后输出的时候指定了以GBk解码,最终不会乱码。


作者:RednaxelaFX
链接:http://www.zhihu.com/question/30977092/answer/50266867
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

题主贴的图完全符合实际情况。它已经很形象的说明了每个步骤会涉及的转码动作。

首先,Java源码文件。这些文件可以是任意字符编码的。
然后在Java的Class文件里存储的字符串是UTF-8编码的。
(具体是一种modified UTF-8,请参考JVM规范:Chapter 4. The class File Format
String content is encoded in modified UTF-8. Modified UTF-8 strings are encoded so that code point sequences that contain only non-null ASCII characters can be represented using only 1 byte per code point, but all code points in the Unicode codespace can be represented. Modified UTF-8 strings are not null-terminated. The encoding is as follows:
……


从Java源码文件到Java Class文件,中间会经过Java源码编译器(例如javac或ECJ)的编译。
也就是说,是Java源码编译器负责将Java源码文件的编码转换为最终的UTF-8。
导致乱码的不是Java源码编译器的“编码”(写出UTF-8)的过程,而是“解码”(读入Java源码内容)的过程。

以javac为例,它有一个参数可以指定输入的Java源码文件的编码:
-encodingencodingSet the source file encoding name, such as EUC-JP and UTF-8. If-encoding is not specified, the platform default converter is used.
关键在于“如果不指定encoding,则使用平台默认的转换器”。
在简体中文的Windows上,平台默认编码会是GBK,那么javac就会默认假定输入的Java源码文件是以GBK编码的。javac能够正确读取文件内容并将其中的字符串以UTF-8输出到Class文件里,就跟自己写个程序以GBK读文件以UTF-8写文件一样。
如果实际输入的确实是GBK编码(GBK兼容ASCII编码)的文件,那么一切都会正常。
但如果实际输入的是别的编码的文件,例如超过了ASCII范围的UTF-8,那javac读进来的内容就会出问题,就“乱码”了。
所以,在题主引用的图里,从橙色的源码文件到蓝色的编译器之间的箭头上,“桥梁”就是这个-encoding参数。

0 0
原创粉丝点击