《编译.java文件时的编码问题》更新版本

采用javac工具,编译.java文件生成.class文件的时候,主要经历两个过程,分别介绍如下。


一、解码.java文件中的字节流得到字符流
输入:.java文件中的字节流
输出:解码.java文件中的字节流得到字符流
注意点:
在编写程序创建.java文件的时候,采用某种编码方案进行编码,将生成的字节流写入.java文件,根据 《编码解码模型和实现》,在解码该字节流的时候必须采用相同的编码方案,否则会导致出现乱码。当出现乱码情形时,javac最后会给出相应的警告信息。
下面举例说明:
1、源程序字符流内容如下:
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
2、采用"utf8"编码方案编码以上源程序字符流,将得到的字节流写入Main.java文件
3、在编译时,指定解码过程中使用的编码方案为"utf8",解码得到字符流
采用的编译命令为"javac -encoding utf8 Main.java",得到的字符流内容如下:
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
4、在编译时,指定解码过程中使用的编码方案为"gbk",解码得到字符流
采用的编译命令为"javac -encoding gbk Main.java",得到的字符流内容如下:
public class Main {
    public static void main(String[] args) {
        String hello = "濂�;
        System.out.println(hello);
    }
}

出现了乱码情形,javac给出了图1中的警告信息。(图1中的错误信息在即将介绍的第二个过程中产生)

                                                           图1

《编译.java文件时的编码问题》更新版本_第1张图片

备注:

编译过程中解码得到的字符流是个中间结果,并不能被我们获得。以上"3和4"中所展现的编译过程中解码得到的字符流是通过“文本编辑器中,指定编码方案解码文件中字节流”的方式模拟获得的。


二、对过程1得到的字符流进行语法分析,编码生成字节流写入.class文件

输入:过程1中解码得到的字符流
输出:对输入中的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入.class文件
注意点:javac最后会给出“对输入中的字符流进行语法分析,转换中遇到的警告和错误信息”。


下面再举几个例子进行说明:
1、例子1
1)Java程序源代码
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
2)采用"utf8"编码方案编码1)中的Java程序源代码,得到字节流写入Main.java文件
3)使用"javac -encoding utf8 Main.java"命令进行编译
i、编译过程1
采用"utf8"编码方案解码Main.java文件中的字节流,得到字符流如下:
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
ii、编译过程2

对编译过程1中解码得到的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入Main.class文件


2、例子2
1)Java程序源代码
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
2)采用"utf8"编码方案编码1)中的Java程序源代码,得到字节流写入Main.java文件
3)使用"javac -encoding gbk Main.java"命令进行编译
i、编译过程1
采用"gbk"编码方案解码Main.java文件中的字节流,得到字符流如下:
public class Main {
    public static void main(String[] args) {
        String hello = "濂�;
        System.out.println(hello);
    }
}
遇到了乱码情形,javac给出图1中的警告信息。
ii、编译过程2
对编译过程1中解码得到的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入Main.class文件

查看编译过程1中解码得到的字符流,可以发现hello所表示的字符串没有正确的结束双引号。因而javac给出图1中的错误信息。


3、例子3
1)Java程序源代码
public class Main {
    public static void main(String[] args) {
        String hello = "好 ";
        System.out.println(hello);
    }
}
2)采用"utf8"编码方案编码1)中的Java程序源代码,得到字节流写入Main.java文件
3)使用"javac -encoding gbk Main.java"命令进行编译
i、编译过程1
采用"gbk"编码方案解码Main.java文件中的字节流,得到字符流如下:
public class Main {
    public static void main(String[] args) {
        String hello = "濂�";
        System.out.println(hello);
    }
}
出现了乱码情形,javac给出图2中的警告信息。
ii、编译过程2
对编译过程1中解码得到的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入Main.class文件

                                                          图2



4、例子4
1)Java程序源代码
public class Main {
    public static void main(String[] args) {
        char hello = '!';
        System.out.println(hello);
    }
}
2)采用"gbk"编码方案编码1)中的Java程序源代码,得到字节流写入Main.java文件
3)使用"javac -encoding utf8 Main.java"命令进行编译
i、编译过程1
采用"utf8"编码方案解码Main.java文件中的字节流,得到字符流如下:
public class Main {
    public static void main(String[] args) {
        char hello = '��';
        System.out.println(hello);
    }
}
出现了乱码情形,javac给出图3中的警告信息。

ii、编译过程2
对编译过程1中解码得到的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入Main.class文件

查看编译过程1中解码得到的字符流,可以发现hello所表示的字符包含了太多字符。因而javac给出图3中的错误信息。

                                                         图3

《编译.java文件时的编码问题》更新版本_第2张图片


5、例子5

1)Java程序源代码
public class Main {
    public static void main(String[] args) {
        String hello = "好";
        System.out.println(hello);
    }
}
2)采用"gbk"编码方案编码1)中的Java程序源代码,得到字节流写入Main.java文件
3)使用"javac -encoding utf8 Main.java"命令进行编译
i、编译过程1
采用"utf8"编码方案解码Main.java文件中的字节流,得到字符流如下:
public class Main {
    public static void main(String[] args) {
        String hello = "��";
        System.out.println(hello);
    }
}

出现了乱码情形,javac给出图4中警告信息。


ii、编译过程2

对编译过程1中解码得到的字符流进行语法分析,转换,采用".class文件规范约定的特定的UTF-8变种编码方案"进行编码得到字节流,写入Main.class文件

                                                          图4


你可能感兴趣的:(《编译.java文件时的编码问题》更新版本)