Java程序设计中对Unicode的支持

来源 :电脑知识与技术 | 被引量 : 0次 | 上传用户:luck88888
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:在信息国际化的今天,正确处理不同的语言文字已经成为绝大多数软件系统的必备功能,该文介绍了在Java程序设计中如何处理和显示不同的语言文字,尤其是非英文字符的处理。本文从基本的编码知识入手,详细介绍了Java语言中编码转换的技术,并给出了可以用于实际开发的实例代码,为构建国际化的Java软件系统打下良好的基础。
  关键词:Java程序设计;Unicode字符集;编码/解码
  中图分类号:TP391文献标识码:A文章编号:1009-3044(2007)03-10773-01
  
  1 引言
  
  在基于Java程序设计中,我们经常碰到非英文字符处理及显示的问题。一大堆看不懂的乱码肯定不是任何人所希望的结果,怎样才能够让那些基于特定字符集编码的非英文字符正确显示呢? 怎样才能够恰当地选择字符集编码方式并正确地处理?本文从基本的字符集知识出发,通过对Java程序设计中有关编码转换的问题进行的分析并结合编程实例,详细介绍Java的多语言支持(Unicode编码)特性。
  
  2 关于字符集的知识
  
  正如大家所知,计算机的信息处理建立在二进制之上,可以这么说,计算机只理解0/1,为了便于阅读和理解,需要将这些0/1的串映射为人可以阅读的字符,这些映射称之为字符集;而字符在字符集中的编码称为字符编码[4]。例如“A”在ASCII字符集中的编码为“0x41”。早期的计算机系统使用了7位二进制的ASCII编码作为缺省的编码方式,于是,在计算机中一切处理程序最初都是以单字节编码为准进行处理。对于英文来说,ASCII码0-127就足以代码所有字符,对于其它语言,如中文,日文等,则必须使用两个字节(byte)来代表一个字符,在习惯上称为双字节(即DBCS:Double-Byte Character Set),相对的,英文的字符编码就称为单字节SBCS(Single-Byte Character Set)。按照这种使用双字节来编码的思路,发展出了简体中文的GB2312,繁体中文的BIG5和日文的SJIS等针对特定语言的字符集。当不同语言的字符混合在一起的时候,必须经过字符集的转换,非常麻烦。例如:中英文混合情况。为解决这个问题,国际标准组织提出了容纳全世界所有语言文字的Unicode字符集。
  Unicode的学名是“Universal Multiple-Octet Coded Character Set”,简称为UCS[2]。UCS可以看作是“Unicode Character Set”的缩写。UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是占用双字节的Unicode编码,UCS-4就是占用4个字节的Unicode编码[4]。本文中所有的内容均以UCS-2为准。
  在Unicode出现之前,许多的信息系统和数据都是基于特定字符集编码开发的,例如,大量的中文电子文档,企业遗留的财务系统,服务部门的计费系统等等。当需要对旧的信息系统和数据进行升级时,系统对多语言支持往往是很重要的部分,在信息国际化的大环境中非常必要的。但很多开发人员没有认识到Unicode编码是多语言支持的核心,或者不熟悉Java语言中正确的编码转换方法,经常写出这样的代码:
  new String(source.getBytes("GB2312"), "ISO8859-1")
  new String(source.getBytes("ISO8859-1"), "GB2312")
  这样的代码存在如下的问题:(1)可读性差,不便于维护;(2)将系统和 GB2312 字符集紧紧绑在一起,多语言支持难以实现;(3)每次都要进行 new 操作,频繁的产生不必要的对象,消耗系统资源。
  事实上,Java语言在设计之初,就考虑到对多语言的支持,默认在Java程序内部使用Unicode字符集,在本文接下来的部分就Java语言的这一特性进行详细的介绍。
  
  3 Java程序设计中的编码转换
  
  在Java程序内部,所有的字符都是按照Unicode字符集来编码,所以在Java程序运行时,就存在由一个本地字符集(与特定语言相关的操作系统)编码向Java内部Unicode字符集编码的转换过程,称为解码(Decoder);同样的,由Java程序内部输出信息,是从Unicode字符集编码向本地字符集转换的过程就是编码(Encoder)[1]。
  Java程序中保证非英文字符能够被正确显示的条件只有一个:解码过程和编码过程使用相同或者兼容的字符集编码。
  从JDK1.4起,Java提供了java.nio.charset包,其中有三个类用于解码和编码:Charset、CharsetEncoder和CharsetDecoder来帮助我们完成编码转换[3],下面我们就用这三个类来演示Java程序设计中的编码转换。
  在Java程序设计中默认支持下列字符集编码[3]:
  US-ASCII:7 位 ASCII;
  ISO-8859-1:ISO 拉丁字母;
  UTF-8:8 位 UCS 转换格式;
  UTF-16BE:16 位 UCS 转换格式,大尾数法字节顺序;
  UTF-16LE:16 位 UCS 转换格式,小尾数法字节顺序;
  UTF-16:16 位 UCS 转换格式,用标记(marker)识别的字节顺序。
  然后,不同的平台可能支持特定于该平台的额外字符集(例如,在 Windows 平台上,您会发现它支持 Windows-1252 字符集)。如果您需要支持其他的字符集,您可以创建自己的字符集。请参阅 java.nio.charset.spi 包中的 CharsetProvider API[1]。
  在得到一个解码器或编码器之前,需要获得用于特定字符集的Charset 。例如,GB2312 是用于GB2312字符集的名称。您只需象下面这样把该名称传递到 Charset 的 forName() 方法中即可:
  Charset charset= Charset.forName("GB2312");
  一旦有了 Charset,只需按如下所示請求 CharsetDecoder 和 CharsetEncoder:
  CharsetDecoder decoder = charset.newDecoder();
  CharsetEncoder encoder = charset.newEncoder();
  有了解码器和编码器后,您就可以在特定字符集编码和Unicode字符集合之间进行转换了,如下所示:
  ByteBuffer bytes = …;
  CharBuffer chars = decoder.decode(bytes);
  bytes = encoder.encode(chars);
  以字符“中”为例,可通过以下方式得到其在GB2312字符集中编码为“D6D0”。这是一个编码过程。
  String str = "中";
  String CHARSET = "GB2312";
  char nativeChars[] = str.toCharArray();
  Charset nativeCharset = Charset.forName(CHARSET);
  CharBuffer nativeCharBuffer = CharBuffer.wrap(nativeChars);
  CharsetEncoder encoder = nativeCharset.newEncoder();
  ByteBuffer nativeBytebuffer = encoder.encode(nativeCharBuffer);
  byte[] nativeBytes = nativeBytebuffer.array();
  System.out.println("\n#----- " + CHARSET + "encoding output -----#");
  for (int i = 0; i < nativeBytes.length; i++)
  {System.out.print(Integer.toHexString('\u00FF' & nativeBytes[i]).toUpperCase());}
  GB2312字符集編码的输出结果:
  #----- GB2312 encoding output -----#
  D6D0
  而后,我们将字符“中”的GB2312字符集编码转换为Unicode字符集编码,这是一个编码过程。
  CharsetDecoder unicodeDecoder = nativeCharset.newDecoder();
  CharBuffer unicodeCharbuffer = unicodeDecoder.decode(nativeBytebuffer);
  char unicodeChars[] = unicodeCharbuffer.array();
  System.out.println("\n#----- Unicode encoding output -----#");
  for (int i = 0; i < unicodeChars.length; i++)
  {System.out.print(Integer.toHexString(unicodeChars[i]).toUpperCase());}
  System.out.println("\n" + String.valueOf(unicodeChars));
  Unicode字符集编码的输出结果:
  #------ Unicode encoding output ------#
  4E2D
  中
  字符“中”的Unicode字符集编码为“4E2D”,并可以被正确的显示。
  类似的,我们可以获得字符“中”在日文字符集SHIFT-JIS中的编码为“9286”,从SHIFT-JIS字符集向Unicode字符集编码转换的结果仍为“4E2D”。
  String str = "中";
  String CHARSET = "SHIFT-JIS";
  char nativeChars[] = str.toCharArray();
  … …
  输出结果:
  #------ SHIFT-JIS encoding output ------#
  9286
  #------ Unicode encoding output ------#
  4E2D
  中
  通过以上的程序实例,可以得出结论:无论字符原来用何种本地字符集表示,在Unicode字符集中都被表示成相同的编码。或者说,Unicode字符集和语言的种类无关。
  可以推断出,无论输入的数据最初由何种字符集编码表示,只要在进入Java程序后,进行Unicode字符集编码转换,并按照Unicode字符集编码输出,都可以被正确的显示。Unicode字符集为不同语言中的所有字符都提供了唯一的编码。
  那么,我们现在就可以回答本文开篇提出的两个问题。
  第一,借助于java.nio.charset包中的Charset、CharsetEncoder和CharsetDecoder将特定字符集编码的字符转换为Unicode字符集编码;
  第二,选择Unicode字符集编码将字符输出。
  做到了以上两点,处理任何语言的字符都不会遇到类似于乱码的显示问题。
  
  4 结束语
  
  本文从Unicode字符集编码角度分析了Java的多语言支持特性,并对由字符集引起的显示问题进行了分析和解答,相信大家能够更好的理解和运用这一技术,从长远角度出发,设计,实现符合国际化规范的应用系统。
  参考文献:
  [1](美)Bruce Eckel. Java编程思想[M]. 机械工业出版社,2002.9.P170-174.
  [2](美)The Unicode Consortium. The Unicode Standard, Version 4.0[M]. Addison-Wesley出版社,1996.
  [3]Unicode官方网站. http://www.unicode.org/.
  [4]Java API文档. http://java.sun.com/.
  本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
其他文献
摘要:在微软某些产品成为事实标准的时代,对这些产品发起挑战是一件困难的事情,但并非是不可能的事情,依靠着技术创新,永中集成Office和桌面Linux作出了典范,并且正朝着正确的方向前进,只要二者能够尊重用户使用习惯、提高兼容性和增强扩展性,打破微软垄断将不再是问题。  关键词:技术创新;平台移转  中图分类号:TP316 文献标识码:A文章编号:1009-3044(2007)03-10791-0
期刊
摘要:动态电路的一个特征是当电路的结构或元件的参数发生变化时,可能使电路改变原来的工作状态,转变到另一个工作状态,这种转变往往需要一个过程,在工程上称为过渡过程。本文以动态电路理论中一阶动态电路用三要素的方法分析计算、二阶以及二阶以上的动态电路用拉普拉斯变换分析求解为例,详述了如何分别运用MATLAB语言编程和应用Simulink模块的方法来对电路进行仿真分析和计算。结论表明,应用MATLAB可以
期刊
摘要:简要回顾了常见的办公OA系统结构和开发技术,分析了B/S结构下OA开发的系统架构、办公应用需求以及开发中存在的问题,设计了一种集成办公软件RedOffice的OA系统。实践证明,该系统可以满足办公需求。  关键词:B/S结构;OA系统;办公应用需求;RedOffice  中图分类号:TP317 文献标识码:A 文章编号:1009-3044(2007)03-10744-02    1 引言  
期刊
摘要:本文介绍了VRML与JAVA、JAVASCRIPT通讯的原理、实现方法以及各自的性能特点,重点研究了JAVA、JAVASCRIPT和VRML在三维建模方面的结合应用技术,并给出了实例。  关键词:虚拟现实建模语言;交互;EAI;API  中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)03-10764-01    1 引言    近年来,随着网络技术和WWW的发展
期刊
摘要:硬盘并没像PC的“摩尔定律”一样发展,硬盘成高性能PC发展的绊脚石。新兴的SSD技术日益成熟,这种新技术将改进PC系统结构。本文介绍最新SSD技术的进展,并利用SSD技术对传统的PC存储系统结构进行改进的几种方案及优劣比较。  关键词:SSD;存储系统结构;硬盘;Nand Flash  中图分类号:TP334文献标识码:A文章编号:1009-3044(2007)03-10762-02    
期刊
摘要:针对现有车载MP3播放器的不足,设计了一个基于S3C2410芯片的μClinux环境下的车载MP3播放系统。详细介绍了嵌入式μClinux操作系统和由ARM9芯片S3C2410构建的MP3播放器的硬件结构和软件系统。  关键词:车载MP3; μClinux;S3C2410  中图分类号:TP311文献标识码:A 文章编号:1009-3044(2007)03-10756-02    1 引言 
期刊
摘要:提出了以Visual C++为开发工具,基于OpenGL技术,开发军用物资装载仿真系统的具体方案。采用数值仿真与可视化技术相结合的方法,建立了军用物资装载模型,对物资装载量与装载方式进行仿真,并得出直观的计算结果,为实际货运装载提供理论依据。  关键词:OpenGL;三维模型;虚拟装载  中图分类号:TP391 文献标识码:A文章编号:1009-3044(2007)03-10802-02  
期刊
摘要:随着计算机技术飞速发展,传统的纸质地图在表现形式及信息查詢方面已越来越难以满足人们对地图的使用需求,如何将互联网用于地图信息管理已成为当前研究的重点。本课题主要研究内容是利用Ajax框架开发“web电子地图系统”,满足用户对地图搜索、定位等功能模块在性能方面上的要求。  关键词:Ajax; web电子地图; Hibernate; LRU  中图分类号:TP399 文献标识码:A文章编号:10
期刊
摘要:本文介绍了在Windows的新版本“Windows Vista”中将要使用的新一代标记语言XAML,给出了它的定义、规则。对新一代编程语言的发展方向作了一定的探讨。  关键词:XAML;Windows Vista;标记语言  中图分类号:TP312文献标识码:A 文章编号:1009-3044(2007)03-10774-02    1 引言    下一个版本的Microsoft Window
期刊
摘要:Visual Basic具有强大的数据库功能,是开发数据库管理系统的常用工具。输入设计是系统设计中一个重要部分,良好的输入,可以确保数据的准确性和可靠性,数据输入有效性监测是输入设计重点考虑的问题。  关键词:数据输入;有效性监测;主要措施;实现手段  中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)03-10768-03    1 引言    Visual Ba
期刊