字符集的发展历史
ASCII control characters |
00 NULL (NULL character) |
01 SOH (Start of Header) |
02 STX (Start of Text) |
03 ETX (End of Text) |
04 EOT (End of Transmission) |
05 ENQ (Enquiry) |
06 ACK (Acknowledgement) |
07 BEL (Bell) |
08 BS (Backspace) |
09 HT (Horizontal Tab) |
10 LF (Line feed) |
11 VT (Vertical Tab) |
12 FF (Form feed) |
13 CR (Carriage return) |
14 SO (Shift Out) |
15 SI (Shift In) |
16 DLE (Data link escape) |
17 DC1 (Device control 1) |
18 DC2 (Device control 2) |
19 DC3 (Device control 3) |
20 DC4 (Device control 4) |
21 NAK (Negative acknowledge) |
22 SYN (Synchronous idle) |
23 ETB (End of transmission block) |
24 CAN (Cancel) |
25 EM (End of medium) |
26 SUB (Substitute) |
27 ESC (Escape) |
28 FS (File separator) |
29 GS (Group separator) |
30 RS (Record separator) |
31 US (Unit separator) |
127 DEL (Delete) |
32 space | 64 @ | 96 ` |
33 ! | 65 A | 97 a |
34 " | 66 B | 98 b |
35 # | 67 C | 99 c |
36 $ | 68 D | 100 d |
37 % | 69 E | 101 e |
38 & | 70 F | 102 f |
39 ' | 71 G | 103 g |
40 ( | 72 H | 104 h |
41 ) | 73 I | 105 i |
42 * | 74 J | 106 j |
43 + | 75 K | 107 k |
44 , | 76 L | 108 l |
45 - | 77 M | 109 m |
46 . | 78 N | 110 n |
47 / | 79 O | 111 o |
48 0 | 80 P | 112 p |
49 1 | 81 Q | 113 q |
50 2 | 82 R | 114 r |
51 3 | 83 S | 115 s |
52 4 | 84 T | 116 t |
53 5 | 85 U | 117 u |
54 6 | 86 V | 118 v |
55 7 | 87 W | 119 w |
56 8 | 88 X | 120 x |
57 9 | 89 Y | 121 y |
58 : | 90 Z | 122 z |
59 ; | 91 [ | 123 { |
60 < | 92 \ | 124 | |
61 = | 93 ] | 125 } |
62 > | 94 ^ | 126 ~ |
63 ? | 95 _ |
首先介绍的是ASCII字符集,ASCII(American Standard Code for Information Interchange,美国信息交换标准代码) 起始于50年代后期,1963年由美国国家标准协会提出,最终完成于1967年。在开发ASCII码的过程中,在字符长度的问题上面(6位、7位、8位?)产生了很大的争议,不能使用替换字符则ASCII不能是6位编码,8位编码版本的费用高,在当时年代每位的存储空间成本非常昂贵,所以8位编码版本也被排除,最终是7位编码的ASCII码。由97 ~ 122的顺序表示26个小写字母、65 ~ 90的顺序表示26个大写字母、48 ~ 57的顺序表示0 ~ 9的10个数字、32个符号、33个句柄和一个空格组成。
什么是7位编码呢?在计算机中,一切数据都是以字节流的形式存在的,一个字节就是8个比特位(8个bit),所以ASCII编码使用一个字节中的7个比特位(7个比特),表示整数0 ~ 127。也就定义了整数到128个字符的映射关系。
字符定义?字符(Character)是一个信息单位。简单来说就是一个汉字、英文或者其他西方语言的字母。用整数和字符完成映射,例如:65 --> A,传入一个整数表明这个数是字符型,计算机就会显示为字符啦。
ASCII字符集的意义?ASCII字符集表示了英文字母、数字、特殊字符、控制符,它是所有字符集的老祖宗,是计算机编码的基础,以后所有其他的字符编码都需要兼容它。
ASCII码的缺点?一个字节可以表示256个状态(0 ~ 255),但是ASCII字符只使用了128个,后面的128个一直都是空的。只能表示一些基本英文字母、阿拉伯数字和英式标点符号。所以只适用于英语语系的国家,不适用于汉字!
ISO8859-1(Latin-1)
上述可以看出,ASCII码字符集所包含的128个字符是不能够满足要求的,并且只是用了128个字符,后面的128位是空的。于是就有了ISO8859-1,又叫Latin-1,包含了256个字符,它是兼容ASCII码的,前面的128个字符与ASCII码完全一致。后面的128个包含了西欧语言、泰语、阿拉伯语、希腊语等来对应相应的文字字符。
GB2312
随着时代的发展,计算机开始逐渐的在东亚流行,我国计算机开始普及后,发现计算机没办法表示当地字符,让我们感到不方便,于是出现了GB2312。GB2312是中国国家标准简体中文字符集,是由中国国家标准总局于1980年发布的,支持6763个常用的汉字和682个其它字符,例如:数字符号、罗马希腊的字母以及日文的假名。用两个字节来表示1个汉字,一个字节表示一个字符。两个字节可以表示 2^16 = 65536个状态,即使汉字再多也可以全部包含进来。后来又有了GBK,GB18030。GB指的就是国标的意思,为了可以显示中文而设计的。
BIG5(大五码)
GB2312是不支持繁体中文的字符,台湾人民的使用就不方便了,于是我国的台湾同胞们自己搞了一套显示繁体中文的大五码 BIG5,是繁体中文社区中最常用的汉字字符集编码,总共13060个汉字,普及于台湾、香港以及澳门等繁体中文通行区,但这不是国家标准,只是业界标准罢了!
GBK
中国是有使用繁体字的需求的,于是GBK增加了对繁体字的支持,是在1995年被提出来的。兼容GB2312,依旧是使用2个字节来表示,可以表示21886个字符。总计收录了21003个汉字,包括常用的繁体汉字以及日韩汉字等。GBK是微软公司利用了GB2312来使用的编码空位来制定的编码。
GB18030
GB18030是最新的中文码表,采用多字节编码,每个字可以由1个、2个或者4个字节组成。可以有效的处理部分人名字的生僻字无法显示在计算机上。GB18030是在2005年由中国国家标准管理委员会提出来的,总计收录70244个汉字,支持少数民族的文字、繁体汉字以及日韩汉字等。
- 一个字节兼容 ASCII 编码
- 两个字节兼容 GBK 编码
- 4个字节支持新增的字符
我们通过以上的字符编码可以知道,全世界各个地方都有属于自己的文字编码,再加上经常不交流,不互通会造成乱码的问题。
那么如多有一种可以统一的字符集,这种字符集把所有的语言字符都收纳其中,每一个字符都给予一个全球独一无二的编码,那么乱码的问题不就可以解决了!于是,全球所有国家和民族使用的所有语言字符的统一字符集就出现了,即Unicode字符集。
Unicode字符集
Unicode字符集是为了给全世界所有的字符一个唯一的编码,这样就不会再造成乱码问题,"唯一"也对应着英文中的 "unique",编码的英文是 "code",所以这样由来。
Unicode使用了字符集和编码分开的策略。Unicode字符集统一采用两个字节表示一个字符,包括英文字母也是如此。但是,由于英文占的很多,这里的多是指占互联网信息的绝大部分。在真实的传输和存储过程中,会造成很大的浪费。所以,目前主要采用的是UTF-8编码来实现的具体的传输与存储。
UTF-8是变长编码,使用1 ~ 6个字节编码Unicode字符。西欧字符仍然是1个字节,汉字3个字节以及2个字节表示其它,例如,拉丁文等。
UTF-16使用2个或者4个字节为每个字符编码,不兼容ASCII码。常用的60000余个字符使用两个字节编码,其余使用4个字节编码。但是实际上,多数人都不会用到超过65535个以外的字符!
UTF-32使用固定的4个字节来表示一个字符,不兼容ASCII码。但是存储空间浪费,一直有利用效率的问题,所以一般很少使用。
注意:
对于字符集发展历史的这张图,都是兼容ASCII码的,像箭头向下的GBK是兼容GB2312,而GB18030是兼容GBK的,Unicode中只有UTF-8是兼容ASCII码的,其它两种UTF-16和UTF-32编码是不兼容ASCII码的。
目前主流使用UTF-8编码(8-bit Unicode Transformation Format)。
字符型
java中的字符型在内存中占2个字节,使用单引号来表示字符常量。例如:'a' 表示的就是一个字符,但是它与双引号 "a" 表示的是不同的, "a" 表示的是一个字符的字符串。
char字符类型可以表示Unicode编码表中的字符,占2个字节,可以有65536个字符。
代码示例
/**
* 测试字符型
* 十六进制值表示
* 转义字符
*/
public class TestChar{
public static void main(String[] args){
// 简单演示
char a = 'a';
char loveChina = '家';
// Unicode具有0 ~ 65535之间的编码,通常也可以从 '\u0000' 到 '\uFFFF'之间的十六进制值来
表示(前缀是u:表示Unicode)
char u1 = '\u0001';
// 转义字符
char u2 = '\t'; // 表示制表符(Tab键)
}
}
转义符 | 含义 | Unicode |
\b | 退格(backspace) | \u0008 |
\t | 制表符(Tab) | \u0009 |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\n | 换行 | \u000a |
\\ | 反斜杠 | \u005c |
\r | 回车 | \u000d |
对于以上常见转义字符,可能大家不明白制表符是什么,我这里在 IntelliJ IDEA Community Edition 2023.2.2(简称IDEA)开发工具中为大家演示一下,我们直接看输出结果,见下图:
这里我打印了3个字符,输出的格式可以看出,它们之间是有一个大空格的,就类似于一个表格连接着一个表格一样,这个就是制表符。
注意:
一对单引号是字符型,比如 'L',而一对双引号是字符串,java语言中没有把字符串当作基本数据类型,而是把它放在了String类下面,但是其实质就是char字符组成的数组,一种字符序列(char sequence)。关于数组以及String类的使用我们后续进行讲解!