如下代码:
public class Example018 { public static void main(String[] args) { byte bs[] = new byte[256]; for (int i = 0; i < 256; i++) { bs[i] = (byte) i; } string(bs);// 调用1 string(bs, "iso-8859-1");// 调用2 string(bs, "gbk");// 调用3 string(bs, "utf-8");// 调用4 } static void string(byte[] bs) { String str = new String(bs); // 使用String(byte[])构造函数 for (int i = 0, length = bs.length; i < length; i++) { System.out.print((int) str.charAt(i) + " "); } } static void string(byte[] bs, String charset) { try { String str = new String(bs, charset);// 使用String(byte[],charset)构造函数 for (int i = 0, length = bs.length; i < length; i++) { System.out.print((int) str.charAt(i) + " "); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
结果说明:
在上述代码中,除了调用2可以正确编译并执行得到意料结果以外,其他的三个调用都不会正确执行。
结果分析:
上述代码的四个调用都使用了字符串的字节数组构造函数。在API中,对这个构造函数的描述是:在通过解码使用平台缺省字符集的指定byte 数组来构造一个新的String 时,该新String 的长度是字符集的一个函数,因此,它可能不等于 byte 数组的长度。当给定的所有字节在缺省字符集中并非全部有效时,这个构造器的行为是不确定的。
ISO-8859-1 是唯一能够让上述程序按顺序打印从0到255的整数的缺省字符集,它更为大家所熟知的名字是Latin-1。
事实+:
字符集:被编码的字符集合和字符编码模式的结合物。换句话说,字符集是一个包,包含了字符、表示字符的数字编码以及在字符编码序列和字节序列之间来回转换的方式。转换模式在字符集之间存在着很大的区别:某些是在字符和字节之间做一对一的映射,但是大多数都不是这样。
- ISO-8859-1:最早的编码,和ASCII编码相似。属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列,无法表示中文。
- GB2312/GBK:专门用来表示汉字,是双字节编码,而英文字母和ISO-8859-1一致(兼容ISO-8859-1编码)。其中GBK编码能够用来同时表示繁体字和简体字,而GB2312只能表示简体字,GBK是兼容GB2312编码的。
- UNICODE:最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,不兼容ISO-8859-1。
- UTF:由于UNICODE编码不兼容ISO-8859-1,而且容易占用更多的空间,所以UNICODE不便于传输和存储,因此而产生了UTF编码,UTF编码兼容ISO-8859-1编码,同时也可以用来表示所有语言的字符。UTF编码是不定长编码,每一个字符的长度从1-6个字节不等。另外,UTF编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节。
参考资料:
1、http://blog.csdn.net/xiongchao2011/article/details/7276834
2、http://www.blogjava.net/thisliy/archive/2009/12/09/305313.html
3、http://bbs.csdn.net/topics/350128607
(注:本【java解惑】系列,均是博主阅读《java解惑》原书后,将原书上的讲解和例子部分改编,然后写成博文进行发布的。所有例子均亲自测试通过,并共享在github上。通过这些例子,激励自己,惠及他人。同时,本系列所有博文会同步发布在博主个人微信公众号(搜索“爱题猿”或者“ape_it”),方便大家阅读。如果文中有任何侵犯原作者权利的内容,请及时告知博主,以便及时删除;如果读者对文中的内容有异议或者问题,欢迎通过博客留言或者微信公众号留言等方式共同探讨。)
源代码地址:https://github.com/rocwinger/java-disabuse