深入Java中文问题及最优解决方法(1)
说明:本文为作者原创,作者联系地址为: josserchai@yahoo.com 。由于Java编程中的中文问题是一个老生常谈的问题,在阅读了许多关于Java中文问题解决方法之后,结合作者的编程实践,我发现过去谈的许多方法都不能清晰地说明问题及解决问题,尤其是跨平台时的中文问题。于是我给出此篇文章,内容包括对控制台运行的class、Servelets、JSP及EJB类中的中文问题我剖析和建议解决办法。希望大家指教。
Abstract:本文深入分析了Java程序设计中Java编译器对java源文件和JVM对class类文件的编码/解码过程,通过此过程的解析透视出了Java编程中中文问题产生的根本原因,最后给出了建议的最优化的解决Java中文问题的方法。
1、中文问题的来源
计算机最初的操作系统支持的编码是单字节的字符编码,于是,在计算机中一切处理程序最初都是以单字节编码的英文为准进行处理。随着计算机的发展,为了适应世界其它民族的语言(当然包括我们的汉字),人们提出了UNICODE编码,它采用双字节编码,兼容英文字符和其它民族的双字节字符编码,所以,目前,大多数国际性的软件内部均采用UNICODE编码,在软件运行时,它获得本地支持系统(多数时间是操作系统)默认支持的编码格式,然后再将软件内部的UNICODE转化为本地系统默认支持的格式显示出来。Java的JDK和JVM即是如此,我这里说的JDK是指国际版的JDK,我们大多数程序员使用的是国际化的JDK版本,以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节编码语言,为了能让计算机处理中文,我们自己制定的gb2312、GBK、GBK2K等标准以适应计算机处理的需求。所以,大部分的操作系统为了适应我们处理中文的需求,均定制有中文操作系统,它们采用的是GBK,GB2312编码格式以正确显示我们的汉字。如:中文Win2K默认采用的是GBK编码显示,在中文WIN2k中保存文件时默认采用的保存文件的编码格式也是GBK的,即,所有在中文WIN2K中保存的文件它的内部编码默认均采用GBK编码,注意:GBK是在GB2312基础上扩充来的。
由于Java语言内部采用UNICODE编码,所以在JAVA程序运行时,就存在着一个从UNICODE编码和对应的操作系统及浏览器支持的编码格式转换输入、输出的问题,这个转换过程有着一系列的步骤,如果其中任何一步出错,则显示出来的汉字就会出是乱码,这就是我们常见的JAVA中文问题。
同时,Java是一个跨平台的编程语言,也即我们编写的程序不仅能在中文Windows上运行,也能在中文Linux等系统上运行,同时也要求能在英文等系统上运行(我们经常看到有人把在中文win2k上编写的JAVA程序,移植到英文Linux上运行)。这种移植操作也会带来中文问题。
还有,有人使用英文的操作系统和英文的IE等浏览器,来运行带中文字符的程序和浏览中文网页,它们本身就不支持中文,也会带来中文问题。
几乎所有的浏览器默认在传递参数时都是以UTF-8编码格式来传递,而不是按中文编码传递,所以,传递中文参数时也会有问题,从而带来乱码现象。
总之,以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正确运行而产生的问题称作:JAVA中文问题。
2、JAVA编码转换的详细过程
我们常见的JAVA程序包括以下类别:
*直接在console上运行的类(包括可视化界面的类)
*JSP代码类(注:JSP是Servlets类的变型)
*Servelets类
*EJB类
*其它不可以直接运行的支持类
这些类文件中,都有可能含有中文字符串,并且我们常用前三类JAVA程序和用户直接交互,用于输出和输入字符,如:我们在JSP和Servlet中得到客户端送来的字符,这些字符也包括中文字符。无论这些JAVA类的作用如何,这些JAVA程序的生命周期都是这样的:
*编程人员在一定的操作系统上选择一个合适的编辑软件来实现源程序代码并以.java扩展名保存在操作系统中,例如我们在中文win2k中用记事本编辑一个java源程序;
*编程人员用JDK中的javac.exe来编译这些源代码,形成.class类(JSP文件是由容器调用JDK来编译的);
*直接运行这些类或将这些类布署到Web容器中去运行,并输出结果。
那么,在这些过程中,JDK和JVM是如何将这些文件如何编码和解码并运行的呢?
这里,我们以中文win2k操作系统为例说明JAVA类是如何来编码和被解码的。
第一步, 我们在中文win2k中用编辑软件如记事本编写一个Java源程序文件(包括以上五类JAVA程序),程序文件在保存时默认采用了操作系统默认支持GBK编码格式(操作系统默认支持的格式为file.encoding格式)形成了一个.java文件,也即,java程序在被编译前,我们的JAVA源程序文件是采用操作系统默认支持的file.encoding编码格式保存的,java源程序中含有中文信息字符和英文程序代码;要查看系统的file.encoding参数,可以用以下代码:
public class ShowSystemDefaultEncoding {
public static void main(String[] args) {
String encoding = System.getProperty("file.encoding");
System.out.println(encoding);
}}
第二步, 我们用JDK的javac.exe文件编译我们的Java源程序,由于JDK是国际版的,在编译的时候,如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式,则javac.exe首先获得我们操作系统默认采用的编码格式,也即在编译java程序时,若我们不指定源程序文件的编码格式,JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然后JDK就把我们的java源程序从file.encoding编码格式转化为JAVA内部默认的UNICODE格式放入内存中。然后,javac把转换后的unicode格式的文件进行编译成.class类文件,此时.class文件是UNICODE编码的,它暂放在内存中,紧接着,JDK将此以UNICODE编码的编译后的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类,并保存在临时文件夹中。如:在中文win2k上,WEB容器就把JSP文件从GBK编码格式转化为UNICODE格式,然后编译成临时保存的Servlet类,以响应用户的请求。
分享到:
相关推荐
### 深入剖析Java编程中的中文问题及建议最优解决方法 #### 1. 中文问题的来源 在探讨Java编程中的中文问题之前,我们首先需要理解计算机编码的基本概念及其发展历史。计算机最初的设计是为了处理单字节字符编码,...
### JAVA中文问题解析和最优解决办法 #### 一、引言 随着信息技术的快速发展与全球化进程的加速,软件开发越来越需要支持多语言环境,特别是中文环境。Java作为一门跨平台的编程语言,广泛应用于Web应用、企业级...
解决Java中文问题的关键在于理解和管理编码的转换过程。以下是一些建议的最优解决方案: 1. 设置正确的file.encoding:在开发环境中,可以通过修改JDK启动参数 `-Dfile.encoding=UTF-8` 来确保源文件的正确解析。 ...
《Java解惑中文版》是一本专为Java程序员设计的指南,旨在帮助读者解决在编程过程中遇到的各种问题,提升程序的健壮性。本书深入浅出地探讨了Java语言的核心概念、常见疑惑以及最佳实践,旨在使开发者能够编写出更...
《Java数据结构和算法中文第二版》是...通过阅读《Java数据结构和算法中文第二版》,开发者可以深入了解数据结构和算法,提升编程能力,解决实际工程中的复杂问题。无论是初学者还是有经验的开发者,都能从中获益匪浅。
《Java算法大全》是一本专为Java程序员设计的算法学习指南,它涵盖了各种常见的数据结构和算法,并以中文形式呈现,方便国内读者阅读。这本书的特点是提供了高清的文字版,而非扫描版,使得阅读和查找信息更为便捷。...
这份"Java经典算法(PPT资源)"包含了9个章节,旨在深入讲解如何使用Java语言来实现各种算法,帮助开发者提升解决问题的能力和代码效率。以下是这些章节可能涵盖的一些关键知识点: 1. **排序算法**:包括冒泡排序、...
标题中的“Java对拼音进行智能切分”涉及的是自然语言处理(NLP)中的一个关键问题,即中文字符到拼音的转换以及拼音的分词。在这个过程中,我们通常需要处理多音字、同音词等问题,以实现更准确的拼音切分。下面将...
总之,《Java数据结构和算法中文第二版》是一本全面且深入的教材,它将带你走进数据结构和算法的世界,通过Java语言实践,提高你的编程技巧和问题解决能力。无论你是初学者还是有经验的开发者,都能从中受益匪浅。
贪心算法则采取局部最优解来尝试达到全局最优,而在无法确保全局最优时,回溯法则是一种有效的试探性解决方法。 最后,对于算法效率的衡量,时间复杂性和空间复杂性分析是不可或缺的部分。这些分析工具帮助开发者...
"Java数据结构和算法中文版"是一本专为中文读者设计的教材,旨在帮助读者深入理解如何在Java语言中有效地组织和操作数据。以下是根据标题、描述以及可能包含的文件内容提炼出的一些关键知识点: 1. **数组**:作为...
《Java版数据结构与算法(中文)》是一个珍贵的学习资源,专为想要深入理解数据结构与算法,并且希望使用Java语言实现的读者设计。数据结构是计算机科学的基础,它研究如何在内存中有效地组织和存储数据,以提高数据...
总之,《数据结构与算法分析(Java语言描述)中文第二版》结合习题答案,为Java开发者提供了一个全面的学习资源,旨在提升他们的数据处理和问题解决能力,这对于软件开发、系统设计和优化等各个方面都至关重要。...
《Java数据结构和算法(中文)》第二版是一本针对Java程序员深入理解数据结构与算法的优秀教材。这本书旨在帮助读者更好地掌握编程基础,提升解决问题的能力,并为实际开发中的高效代码编写提供理论支持。以下是对...
动态规划通常用于优化决策,贪心算法每次做出局部最优决策,回溯法用于在搜索过程中撤销错误决策,分治策略则是将大问题分解为小问题来解决。 此外,学习"JAVA数据结构与算法"还包括理解和实现数据结构和算法的时间...