(转)谈谈对Java中Unicode、编码的理解

来源:互联网 发布:共享单车车辆调度算法 编辑:程序博客网 时间:2024/06/15 02:31

我们经常会遇到编码问题。java号称国际化的语言,是因为它的class文件采用utf-8,而jvm运行时使用utf-16(至于为什么jvm中要采用utf-16,我没看过 相关的资料,但我猜可能是因为java里面一个字符(char)就是16位的,而utf-16正是双字节编码),都是unicode的编码。

unicode 的目标就是能支持世界上所有的字符集,也就是说几乎所有的字符集包含的字符在unicode中都有对应的编码。在unicode中,字符与代码的映射关 系,就是unicode字符集,称为ucs(unicode character set),每个unicode字符编码称为code point(代码点?)。utf-8和utf-16是不同的ucs编码方法,utf就是ucs transformation format。;

在java 中,string的getbytes()方法就是对特定的字符串(unicode)按照给定的字符集进行编码(encode),new string()则可以按照某个字符集将字节流转换回unicode(decode)。java里面的每一个string都是unicode编码。

再来看页面,如果不做特殊处理,form的提交就按照页面的contenttype设置中的字符集进行编码转换,发送到后台,后台必须利用req.setcharacterencoding来指定参数的编码格式(不同的应用服务器应有不同的指定方式),才能正确解码。

java 里面的encode和decode都是相对于unicode而言的,encode的意思是将char[] --> xxx encoding byte[],decode就是由xxx encoding byte[] --> char[]。平常,当我们说“将gbk编码转换为utf-8编码”的时候,实际的意思就是:gbk encoding byte[] --> utf-8 encoding byte[],这种转换只有在需要用byte[]传输数据的时候才有意义,否则便是毫无意义的。

首先要说明的一点是:java中的string对象就是一个unicode编码的字符串。

但是,我们通常会听到有人说:“我们需要将string由iso-8859-1转换为gbk编码”,这又是怎么回事呢?实际上,我们并不是要“将 一个由iso-8859-1编码的string转换为gbk编码的string”,反复说明的是,java中的string都是unicode编码的,所以不存在“iso- 8859-1编码的string”或“gbk编码的string”这样的说法。而需要转换的唯一的原因是string进行了错误的编码。我们经常会碰到由iso-8859- 1转换为诸如gbk/utf-8等等这样的需求。所谓的转换过程是:string --> byte[] -->string。

也许 你非常清楚这个过程的代码:new string(text.getbytes("iso-8859-1"),"gbk")。但是,要真正理解起来并不是那么简单。表面上看似乎很容易理解, 不就是将text string对象按照iso-8859-1的方式编码为byte[]然后再把它按照gbk的方式转换为string吗?但是这句代码很容易会被误解为: “将text string由iso-8859-1转换为gbk编码”,这种说法是错误的。难道你见过用这样的代码:new string(text.getbytes("gbk"),"utf-8")来对string进行编码转换的吗?

之所以你会经常看到new string(text.getbytes("iso-8859-1"),"gbk")这句代码,是因为一个gbk的字节流被错误地以iso-8859- 1的方式转换为string(unicode)了!发生这种情况最普遍的地方是一个gbk编码的网页向后台提交数据的时候,就有可能会看到这句代码的出 现。gbk的流被错误的当成iso8859-1的流,所以便得到了一个错误的string。由于iso8859-1是单字节编码,所以每个字节被按照原样 转换为string,也就是说,虽然这是一个错误的转换,但编码没有改变,所以我们仍然有机会把编码转换回来!所以那句经典的new string(text.getbytes("iso-8859-1"),"gbk")便出现了。

如果系统误以为是其它编码格式,就有可能再也转换不回来了,因为编码转换并不是负负得正那么简单的


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
原创粉丝点击