java什么是国际化
相关话题
我们知道Unicode为国际化(I18n)提供了坚实的基础。但是Unicode不等同于国际化。使用Unicode的Java语言,若是使用不当,同样达不到国际化的目的。让我们来看一下Java是怎样处理Unicode的。
Java的字符类型
和C语言不同,Java的字符类型“char”是一个16位长的整数,而C语言的char是8位,等同于一个字节,只能表示单字节的字符(拉丁语系文字)。所以Java可以直接用一个char来表示一个Unicode字符(包括中文、英文、日文……),大大简化了字符和字符串的操作。
因为Java字符总是Unicode字符,所以在后文中,如果不加说明,“字符”或“char”都是指16位的Unicode字符,而“字节”或“byte”都是指8位字节。
编码(encoding)
然而,当今多数计算机系统,都是以字节为存储运算的基本单元。这就使得在Java中,用Unicode表示的字符串无法直接写到文件中或保存到数据库中。必须以某一种方式,将字符串转换成便于传输和存储的字节流才行。这种将Unicode字符转换成字节的操作,就叫做“字符编码”(encoding)。
前面说过Unicode有两种字节表示法:UTF-8和UTF-16。所以将Unicode以UTF-8和UTF-16编码是最直接和自然的事了。以上面的“我爱Alibabaあいう”为例,用Big-endian(高位字节在前,低位字节在后)的UTF-16编码,可以表示成:
我们也可以把同样的字符串转换成UTF-8。UTF-8是变长的编码,对于ASCII码字符,不需要改变,就已经是UTF-8了,但一个中文要用三个字节来表示:
使用UTF-16或UTF-8编码的数据,必须使用支持Unicode的软件来处理,例如支持Unicode的文本编辑器。目前存在的大量软件,不一定都支持Unicode。因此我们往往将Unicode转换成某一种本地字符集,例如:
英文可转换成ISO-8859-1。
中文可转换成GB2312、GBK、BIG5或是GB18030等。
日文可以转换成SJIS或ISO-2022-JP等。
韩文可以转换成ISO-2022-KR等。
本地字符集名目之多,无法全部列举。最重要是,大多数字符集只映射到Unicode中的部分字符,且字符集之间互相交错,互不兼容。
那么,如果在将Unicode转换到某一本地字符集时,发现这一编码字符集不包含这个字符,怎么办呢?例如:“我爱Alibaba”这个字符串(简体中文),如果转换成繁体中文的BIG5编码,就会变成:“我?Alibaba”。原来,Unicode规定,转换时碰到“看不懂”的字符,一律用“?(0x3F)”表示。
这就解释了一种常见的“乱码”情形:好端端的页面,显示在浏览器上却变成了无数个问号。原因就是Java在输出网页时,使用了错误的编码方式。