Java中文编码问题研究
摘要:介绍了中文编码同Java的关系。根据Java程序的运行原理,分析了Java单机程序、在服务器上运行的JSP、
Servelets或EJB等与分布式Java程序产生中文乱码的原因,提出了相应的解决方案。
关键词:Java;中文;编码格式;乱码
1问题描述
计算机最初的操作系统支持的编码是单字节的字符编码,
在计算机中一切处理程序最初都是以单字节编码的英文为准
进行处理。为了适应世界其它民族的语言(当然包括汉字),人
们提出了UNICODE编码。它采用双字节编码,兼容英文字符和
其它民族的双字节字符编码,因此,目前大多数国际性的软件
内部均采用UNICODE编码。在软件运行时,它获得本地支持系
统(多数时间是操作系统)默认支持的编码格式,然后再将
软件 内部的UNICODE转化为本地系统默认支持的格式显示出来。
Java的JDK和JVM即是如此,这里说的JDK是指国际版的JDK,
大多数程序员使用的是国际化的JDK版本。汉字是双字节编码
语言,为了能让计算机处理中文,我国自己制定gb2312、GBK、
GBK2K等标准以适应
计算机处理的需求。因此,大部分的操作
系统为了适应中文处理的需求,均定制有中文操作系统,它们
采用的是GBK,GB2312编码格式来正确显示汉字。
由于Java语言内部采用UNICODE编码,所以在Java程序运
行时,就存在着一个从UNICODE编码和对应的操作系统及浏
览器支持的编码格式转换、输入、输出的问题,这个转换过程有
着一系列的步骤,如果其中任何一步出错,则显示出来的汉字
就是乱码,这就是常见的Java中文问题。
2关键问题分析及解决
方案 通常Java程序可以分为以下几个类型:
(1)直接在console上运行的单机程序(包括可视化界面的
类);
(2)在服务器上运行的JSP、Servlets或EJB等;
(3)分布式程序,客户端与服务运行于不同机器,而且语言
环境可能不一致;目前网管应用就属于此种情况。
以上这些类型的Java程序中,都有可能含有中文字符串,
并且经常需要与用户直接交互,用于输出和输入字符,这些字
符也包括中文字符。无论这些Java类的作用如何,这些
Java程序
的生命周期都是这样的:
(1)编程人员在一定的操作系统上选择一个合适的编辑软
件来实现源程序代码并以.java扩展名保存在操作系统中;
(2)编程人员用JDK中的javac.exe来编译这些
源代码,形成.
class类(JSP文件是由容器调用JDK来编译的);
(3)直接运行这些类或将这些类布署到WEB容器中去运
行,并输出结果。
在程序运行过程中,JDK和JVM是按以下的步骤来完成编
解码的过程。
第一步,在中文win2k中用编辑软件如记事本编写一个Java
源程序文件,程序文件在保存时默认采用了操作系统默认支持
GBK编码格式(操作系统默认支持的格式为file.encoding格式)
形成了一个.java文件,即java程序在被编译前,Java源程序文件
是采用操作系统默认支持的file.encoding编码格式保存的,java
源程序中含有中文信息字符和英文程序代码。
第二步,用JDK的javac.exe文件编译Java源
程序。由于JDK
是国际版的,在编译的时候,如果没有用-encoding参数指定Ja-
va源程序的编码格式,则javac.exe首先获得操作
系统默认采用
的编码格式。即在编译java程序时,若不指定源程序文件的编
码格式,JDK首先获得操作系统的file.encoding参数(它保存的
就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然
后JDK就把java源程序从file.encoding编码格式转化为Java内部
默认的UNICODE格式放入内存中。然后,javac把转换后的uni-
code格式的文件进行编译成.class类文件,此时.class文件是U-
NICODE编码的,它暂放在内存中。紧接着,JDK将此以UNI-CODE编码的编译后的class文件保存到操作系统中形成.class
文件。对程序员来说,最终获得的.class文件是内容以UNICODE
编码格式保存的类文件。它内部包含源程序中的中文字符串,
且己经由file.encoding格式转化为UNICODE格式了。
在这一步中,对于JSP源程序文件是不同的。对于JSP,过程
是这样的:即WEB容器调用JSP编译器,JSP编译器先查看
JSP文
件中是否设置有文件编码格式。如果JSP文件中没有设置JSP文
件的编码格式,则JSP编译器调用JDK先把JSP文件用JVM默认
的字符编码格式(也即WEB容器所在的操作系统的默认的file.
encoding)转化为临时的Servlet类,然后再编译成UNICODE格式
的class类,并保存在临时文件夹中。
第三步,运行第二步编译出来的类,分为以下三种情况:
(1)单机程序,运行该类首先需要JVM支持,即操作系统中
必须安装有JRE。运行过程如下:首先java启动JVM,此时JVM读
出操作系统中保存的class文件并把内容读入内存中,此时内存
中为UNICODE格式的class类,然后JVM运行它。如果此类需要
接收用户输入,则类会默认用file.encoding编码格式对用户输入
的串进行编码并转化为unicode保存入内存(用户可以设置输
入流的编码格式)。程序运行后,产生的字符串(UNICODE编码
的)再回交给JVM,最后JRE把此字符串再转化为file.encoding格
式(