谈谈我对Java中Unicode、编码的理解

          我们经常会遇到编码问题。 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-8UTF-16 是不同的 UCS 编码方法, UTF 就是 UCS Transformation Format 。;

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

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

          Java
里面的 encodedecode 都是相对于 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 编码的字符串。

          但是,我们通常会听到有人说: 我们需要将 StringISO-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 StringISO-8859-1 转换为 GBK 编码 ,这种说法是错误的。难道你见过用这样的代码: new String(text.getBytes("GBK"),"UTF-8") 来对 String 进行编码转换的吗?

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

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

 

原址连接:http://blog.csdn.net/soleghost/archive/2006/07/22/959832.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值