`
xwood
  • 浏览: 100692 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

谈谈我对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-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 的流被错误的当成 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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics