`
小杨学JAVA
  • 浏览: 904039 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

转:http://www.cnblogs.com/newstar/archive/2011/06/13/2079870.html

 我们经常会遇到编码问题。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")便出现了。

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

分享到:
评论

相关推荐

    UTF8转Unicode的详细介绍

    它是目前最广泛使用的Unicode编码形式,因为它具有许多优点。UTF8的一个关键特性是它使用不同数量的字节来表示不同的字符。例如,ASCII字符(包含英文、数字和一些基本标点符号)只需要1个字节,而大多数其他Unicode...

    java存取oracle中的COLB类型数据.pdf

    该类提供了两个方法来读取 COLB 数据:getCharacterStream() 方法返回按 Unicode 编码的输入流(java.io.Reader 对象),getAsciiStream() 方法返回按 ASCII 编码的输入流(java.io.InputStream 对象)。 在实际...

    UNICODE系列讲座

    接下来,我们谈谈Unicode在编程语言中的实现。在Java、Python、C#等现代编程语言中,都默认使用Unicode作为字符串的内部表示。这使得开发者能够轻松处理多语言文本,无需关心具体编码问题。例如,在Python中,字符串...

    获取码值(各种类型字符(中、英)的ASCII)和进制转换系统(包括正负数、小数)

    这时,我们需要使用Unicode编码,它是一个包含所有现代字符的全球性标准。在Unicode中,每个字符都有一个唯一的码点,通常用十六进制表示。比如,中文字符“中”的Unicode码点是U+4E2D,转换为十进制就是20013。 接...

    Java IO合集

    3. 字符编码:如ASCII、Unicode(UTF-8)等在Java IO中的应用。 4. 对象序列化:如何保存和恢复对象的状态。 5. 缓冲技术:提高数据读写效率的方法。 6. 套接字编程:实现客户端-服务器通信的基础。 7. 多线程I/O:...

    jfreechart-1.0.13中文乱码,数值显示等问题

    2. 对数据源进行编码转换:确保你的数据源(如CSV或数据库)正确编码为UTF-8,避免在读取时产生乱码。 3. 在生成图表的文本元素时,使用对应的编码设置,如: ```java TextAttribute.FONT, new Font("SimSun", Font....

    java1_chapter2_type_variable.zip

    3. 字符型:char(2字节,Unicode编码,可以表示所有字符,如字母、数字、标点符号等)。 4. 布尔型:boolean(非数值型,仅包含两个值,true和false)。 声明变量时,我们需要指定其数据类型和变量名,例如: ```...

    java面试题(2015)

    - `char` 类型用来存储 Unicode 编码的字符,Unicode 包含了所有常见文字的编码,因此可以存储一个汉字。 8. **用最效率的办法算出2乘以8等于几?** - 使用位移运算符 `来实现乘法操作,如 `2 。这是因为位移...

    Java就业面试题264道(独家奉献)

    - `char` 类型可以存储中文字符,因为Java中`char`类型采用Unicode编码,一个`char`可以表示一个中文字符。 **9. 用最有效率的方法算出2乘以8等于几?** - 使用位移操作`2 可以快速计算2乘以8的结果。 **10. 请设计...

    各大公司企业真实面试题-阳光海融科技面试题请用Java语言编写完成如下任务的程序代码.doc

    **题目描述**:我们知道Java采用的是Unicode,那么我们在编制中文软件时应注意什么? **注意事项**: 1. **编码格式**:确保项目中的所有文件都使用UTF-8编码格式。 2. **国际化资源文件**:使用属性文件来存储不同...

    emoji-cheat-sheet表情包

    在与Emoji相关的开发中,理解Unicode和字符编码也至关重要,因为这直接影响到Emoji在不同环境下的表现。这个压缩包可能包含了一个Web应用程序,让用户可以轻松地探索和使用表情包,提升在线沟通的趣味性和效率。

    ISO-8859.docx

    在Java中,当我们从客户端接收数据时,有时数据可能是按照ISO-8859-1编码的。如果我们要正确处理这些数据,需要将其转换为Java默认或者更通用的UTF-8编码。转换的代码如下所示: ```java public static String ...

    java面试宝典

    在Java中,`char`类型使用Unicode编码,一个`char`可以存储一个中文字符。 10. **逻辑操作符(&,|,^)与条件操作符(&&,||)的区别**: - `&`、`|`、`^`是位运算符,分别对应按位与、按位或、按位异或。 - `&&`、`||`...

    io_输入输出流_序列化反序列化_04.zip

    而字符流则基于Unicode编码,主要用于处理文本数据。字节流包括输入流(InputStream)和输出流(OutputStream),字符流包括Reader和Writer。例如,FileInputStream和FileOutputStream是处理文件的字节流,而 ...

    文本、图形输出

    例如,ASCII编码只支持128个基本字符,而Unicode则包含了全世界几乎所有的字符,因此在处理国际化的软件时,通常选择Unicode编码。 接下来,我们要讨论的是图形输出。图形输出涉及图像和视觉元素的呈现,包括位图和...

    HTML 转码

    在Java中,有`java.net.URLEncoder`类;在PHP中,可以使用`htmlspecialchars`函数等。这些函数和方法能帮助开发者在代码中自动处理HTML转码,确保输出的内容是安全的。 除了基本的转码,还有更高级的概念,比如HTML...

    Android例子源码自定义字体使用和文字倒影处理

    GBK编码在中文字符支持上较全面,但不如Unicode广泛,可能会遇到编码转换的问题。同时,4.4.2版本相对较低,因此在编写代码时要确保对更低版本API的兼容。 通过分析这个例子源码,我们可以学习到如何在Android应用...

    JavaFunctions

    在Java中,字符使用Unicode编码,这比ASCII包含更多的字符集,但在这个特定的函数中,只处理ASCII的小写字母部分。 再者,异常处理是一个重要的Java特性。在上述代码中,如果传入的`letter`不在小写字母范围内,...

    经典Python面试题之Python基础篇.docx

    - **map**: 对序列中的每一个元素应用函数。 - **reduce**: 从左至右累积地将函数应用于序列中的元素。 #### 34. 一行代码实现 9*9 乘法表 ```python print('\n'.join([' '.join([f'{i*j:2}' for j in range(1, 10...

Global site tag (gtag.js) - Google Analytics