`
kobe学java
  • 浏览: 262516 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Java的中文处理学习笔记:Hello Unicode

    博客分类:
  • java
 
阅读更多

 

Java的中文处理学习笔记:Hello Unicode

分类: 计算机基础 Java 10人阅读 评论(0) 收藏 举报

不知道你有没有这样的感受:为什么PHP很少有乱码问题而用Java做WEB应用却这么麻烦呢?为什么在Google上能用简体中文查到繁体中文,甚至日文的结果?而且用Google的时候发现它居然能自动根据我使用浏览器的语言选择自动调出中文界面?

很多国际化应用的让我理解了这么一个道理:Unicode是为更方便的做国际化应用设计的,而Java核心的字符是基于UNICODE的,这一机制为应用提供了对中文“字”的控制(而不是字节)。但如果不仔细理解其中的规范,这种自由反而会成为累赘,从而导致更多的乱码问题:

  1. 关于字符集的一些基本概念;
  2. 试验1:显示系统的环境设置和支持的编码方式;
  3. 试验2:系统缺省编码方式对Java应用的输入输出影响;
  4. 试验3:在WEB应用中输出和输出中的字符集问题;

关于字符集的准备知识:
ISO-8859-1 GB2312 BIG5 GBK GB18030 UNICODE 为什么会有这么多字符集编码方式?

注意:以下说明不是严格定义,一些比喻仅作为方便理解使用。

假设一个字符就是棋盘上的一个棋子,有其固定的坐标,如果需要区别所有的字符,就需要有足够的棋格容纳不同的“字符”。 

英文和欧洲其他语言的单字节字符集(SingleByte Charsets):
首先对于ISO-8859系列的字符集都想象成一个:2^8 = 16 * 16 = 256个格子的棋盘,这样所有的西文字符(英文)用这样一个16×16的坐标系就基本可以覆盖全了。而英文实际上只用其中小于128(\x80)的部分就够了。利用大于128部分的空间的不同定义规则形成了真对其他欧洲语言的扩展字符集:ISO-8859-2 ISO-8859-4等……

GB2312 BIG5 SJIS等多字节字符集(MultiByte Charsets):

对于亚洲语言来说:汉字这么多,用这么一个256格的小棋盘肯定放不下,所以要区别成千上万的汉字解决办法就是用2个字节(坐标)来定位一个“字”在棋盘上的位置,将以上规则做一个扩展:

  • 如果第1个字符是小于128(\x80)的仍和英文字符集编码方式保持兼容;
  • 如果第1个字符是大于128(\x80)的,就当成是汉字的第1个字节,这个自己和后面紧跟的1个字节组成一个汉字;

其结果相当于在位于128以上的小棋格里每个小棋格又划分出了一个16×16的小棋盘。这样一个棋盘中的格子数(可能容纳的字符数)就变成了128 + 128 * 256。按照类似的方式有了简体中文的GB2312标准,繁体中文的BIG5字符集和日文的SJIS字符集等,GB2312字符集包含大约有六仟多个常用简体汉字。

由此可以看出,所有这些从ASCII扩展式的编码方式中:英文部分都是兼容的,但扩展部分的编码方式是不兼容的,虽然很多字在3种体系中写法一致(比如“中文”这2个字)但在相应字符集中的坐标不一致,所以GB2312编写的页面用BIG5看就变得面目全非了。而且有时候经常在浏览其他非英语国家的页面时(比如包含有德语的人名时)经常出现奇怪的汉字,其实就是扩展位的编码冲突造成的。

我把GBK和GB18030理解成一个小UNICODE:GBK字符集是GB2312的扩展(K),GBK里大约有贰万玖仟多个字符,除了保持和GB2312兼容外,繁体中文字,甚至连日文的假名字符也能显示。而GB18030-2000则是一个更复杂的字符集,采用变长字节的编码方式,能够支持更多的字符。关于汉字的编码方式比较详细的定义规范可以参考:
http://www.unihan.com.cn/cjk/ana17.htm

ASCII(英文) ==> 西欧文字 ==> 东欧字符集(俄文,希腊语等) ==> 东亚字符集(GB2312 BIG5 SJIS等)==> 扩展字符集GBK GB18030这个发展过程基本上也反映了字符集标准的发展过程,但这么随着时间的推移,尤其是互联网让跨语言的信息的交互变得越来越多的时候,太多多针对本地语言的编码标准的出现导致一个应用程序的国际化变得成本非常高。尤其是你要编写一个同时包含法文和简体中文的文档,这时候一般都会想到要是用一个通用的字符集能够显示所有语言的所有文字就好了,而且这样做应用也能够比较方便的国际化,为了达到这个目标,即使应用牺牲一些空间和程序效率也是非常值得的。UNICODE就是这样一个通用的解决方案。

UNICODE双字节字符集
所以你可以把UNICODE想象成这样:让所有的字符(包括英文)都用2个字节(2个8位)表示,这样就有了一个2^(8*2) = 256 * 256 = 65536个格子的大棋盘。在这个棋盘中,这样中(简繁)日韩(还包括越南)文字作为CJK字符集都放在一定的区位内,为了减少重复,各种语言中写法一样的字共享一个“棋格”。详细的区位见附录A

Unicode:(DoubleByte Charsets)

什么还要有UTF-8?毕竟互联网70%以上的信息仍然是英文。如果连英文都用2个字节存取(UCS-2),空间浪费不就太多了?所谓UTF-8就是这样一个为了提高英文存取效率的字符集转换格式:Unicode Transformation Form 8-bit form。用UTF-8,UNICODE的2字节字符用变长个(1-3个字节)表示:

  1. 对英文,仍然和ASCII一样用1个字节表示,这个字节的值小于128(\x80);
  2. 对其他语言的用一个值位于128-256之间的字节开始,再加后面紧跟的2个字节表示,一个字符一共是3个字节;

因此,在应用中程序处理过程中所有字符都是16位(双字节),但在存取转换成字节流时使用UTF-8格式转换,对于英文字符来说和原来用ASCII方式存取时相比大小仍然是一样的,而对中文来说和原来的GB2312编码方式相比,大小为:(3字节/2字节)=1.5倍

小节:

假设英文字符集是一个16×16的棋盘,么其他语言的字符集就是把高位区重新分割的(> 128)的中等棋盘,多种字符集之间互不兼容而UNICODE本身就相当于一个256×256的大棋盘,通过一定规则将英文和其他所有语言的字符都包含在内。

最需要注意的是JVM的file.encoding属性,这个属性确定了JVM的缺省的编码/解码方式:从而影响应用中所有字节流==>字符流的解码方式 ,字符流==>字节流的编码方式。

    LINUX下的LOCALE可以通过 LANG=zh_CN; LC_ALL=zh_CN.GBK; export LANG LC_ALL 设置。locale 命令可以显示系统当前的环境设置
    Windows的LOCALE可以通过 控制面板==>区域设置 设置实现

结论1:

JVM的缺省编码方式由系统的“本地语言环境”设置确定,和操作系统的类型无关。所以当设置成相同的LOCALE时,Linux和Windows下的缺省编码方式是没有区别的(可以认为cp1252=ISO-8859-1都是一样的西文编码方式,只包含255以下的拉丁字符),因此后面的测试2我只列出了GNU/Linux下LOCALE分别设置成zh_CN和en_US的测试结果输出。以下测试如果在Windows下分别按照不同的区域和字符集设置后试验的输出是一样的。

 

分享到:
评论

相关推荐

    java4android学习笔记(2-54全)(mars)

    ### Java4Android 学习笔记综合知识点概览 #### 第2课 Java创世纪 ##### 1. 什么是编程? 编程是一种让计算机按照人的意图执行特定任务的过程。它不仅仅是编写代码,更是一种创造性的活动,通过编程可以实现各种...

    java学习笔记.txt

    ### Java学习笔记知识点详解 #### 一、Java的常量 **定义:** - 常量是指在程序运行期间其值不可改变的量。 **分类:** 1. **字符串常量:** - 被双引号包围的字符串,例如`"hello world"`或空字符串`""`。 2. *...

    JDK 良葛格 java 学习笔记6

    ### JDK 良葛格 Java 学习笔记6:深入理解字符串 #### 6.1 认识字符串 ##### 6.1.1 String 类 字符串(String)是一种常见的数据结构,尤其在 Java 编程中占据着重要的位置。字符串是由一系列字符(Char)构成的...

    java学习笔记

    ### Java学习笔记要点 #### 一、Java环境搭建与配置 **1.1 下载官方JDK** - **官网**: [http://www.oracle.com/technetwork/java/index.html](http://www.oracle.com/technetwork/java/index.html) - **步骤**: ...

    Java 学习笔记.pdf

    ### Java 学习笔记知识点概览 #### 一、在命令行执行 Java 1. **编译 Java 文件**: - 使用 `javac 文件名.java` 命令来编译 Java 源代码文件。这将生成一个或多个 `.class` 文件(字节码文件),这些文件的...

    java学习笔记(基础\1)

    ### Java学习笔记(基础1) #### 一、环境的搭建 **1.1 为什么需要环境** - **Java运行环境JDK(包含了JRE)**:JDK (Java Development Kit) 是开发Java程序的基础,它包含了Java运行环境(JRE)以及Java开发工具,...

    java4android 听课笔记 (完整版)

    - 编写`Hello.java`文件,包含`public class Hello`及`main`方法。 - 使用`javac`编译源代码,生成字节码文件`hello.class`。 - 使用`java`命令运行编译后的类。 3. **Java基本概念**: - **环境变量**是操作...

    Java笔记.txt

    **Java IO (Input/Output)**:Java IO 包含了处理输入/输出流的各种类,包括字节流、字符流等。它提供了读取文件、网络通信等功能的基础支持。 **JDBC (Java Database Connectivity)**:JDBC 是 Java 中用于与...

    计算机核心java编程笔记

    为了更好地学习和掌握 Java 语言,本笔记将对 Java 语言的基础知识进行详细的总结和介绍。 一、Java 标识符和关键字 在 Java 语言中,标识符是为方法、变量或其他用户定义项所定义的名称。标识符可以有一个或多个...

    java学习(一).pdf

    而在描述部分提到的“java学习笔记(一)”进一步揭示了这是一份关于Java入门学习的笔记资料。这些内容通常覆盖了Java的基本概念、安装配置以及简单的编程实践等。 #### 二、Java环境搭建与配置 1. **Java下载与...

    马士兵JAVA笔记(全).docx

    马士兵JAVA笔记(全) 本资源是马士兵的JAVA笔记,涵盖了JAVA语言的基础知识,包括标识符、常量、变量、数据类型、运算符、控制流语句等。 标识符是JAVA中的一种符号,用于命名变量、方法、类等。标识符由字母、...

    万和java工程师培训笔记

    根据提供的“万和java工程师培训笔记”部分内容,我们可以总结出以下关键知识点: ### 1. Java 开发环境 - **JDK (Java Development Kit)**:Java开发工具包,包含了编译、运行Java程序所需的工具。 - **JRE (Java...

    java语言本科课堂笔记

    ### Java语言本科课堂笔记知识点概览 #### 一、Java的地位与特点 1. **网络地位**:Java因其跨平台性和强大的网络功能,在网络应用程序领域占据主导地位。 2. **语言地位**:作为一种面向对象的语言,Java在软件...

    java笔记.docx

    ### Java基础知识精讲 #### 一、Java 数据类型概述 Java是一种强类型语言,它将数据分为两大类:基本数据类型和引用数据类型。 - **基本数据类型**:包括数值型...希望这些内容能够帮助到正在学习Java的新手们。

    java基础笔记

    Java基础笔记是一份适合初学者的文档,涵盖了Java编程语言的核心概念和基本知识点,包括标识符的规则、数据类型的分类和使用、变量的声明与初始化、运算符的使用规则、控制流程语句(如if-else和switch-case)以及...

    java计算机核心编程笔记

    《Java计算机核心编程笔记》 Java是一种广泛使用的面向对象的编程语言,其语法严谨,类型系统强大。本笔记将围绕Java的核心概念展开,包括标识符、关键字、数据类型、流程控制、修饰符、变量命名和作用域、以及常用...

    java 计算机编程笔记

    Java是一种广泛使用的面向对象的编程语言,其设计目标是具有高度的可移植性,可编写一次,到处运行。...通过不断地学习和实践,可以深入理解Java语言的高级特性,如面向对象编程、异常处理、多线程、网络编程等。

    JAVA初级笔记汇总

    ### JAVA初级笔记汇总 ...以上总结了Java初级学习阶段的基础知识点,涵盖了从基础概念到变量、数据类型、运算符以及简单的输入处理等内容。这些知识点对于初学者来说至关重要,能够帮助他们打下坚实的基础。

    计算机Java编程笔记

    ### 计算机Java编程笔记知识点详述 #### 一、标识符与关键字 - **标识符**: 在Java中用于命名变量、方法、类等。根据题目提供的内容,标识符可以由数字、字母、下划线`_`及美元符号`$`组成,但需要注意的是,数字不...

Global site tag (gtag.js) - Google Analytics