首先普及一下基本概念:
1.数值(百度百科):指的是用数目表示的一个量的多少;
2.进制(百度百科):也就是进位计数制,是人为定义的带进位的计数方法。对于任何一种进制---X进制,就表示每一位置上的数运算时都是逢X进一位。 十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一,以此类推,x进制就是逢x进位。
现假设有一串葡萄的个数需要表达出来:用二进制表达则为:10101,用十进制表达则为:21,用十六进制表达则为15,因此进制只是数值的表示方式(计数方式),同样的数量用不同的进制有不同的表示,但数值是一样的!
3.二进制:在计算机内部,所有的信息最终都表示为一个二进制的字符串。计算机计算是根据电压的高低变化来计算的,高电压是1,低电压是0,目前只能识别这样的信号,因此只能是二进制。
4.位(bit):是电子计算机中最小的数据单位,每一位的状态只能是0或1。如10101就有5位。
5.字节(byte):1字节(byte)=8位(bit),每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。
在Java中,byte只能表示-128~127范围内的数(即2^8=256个),超出此范围外的数值都表示不了。可以用idea声明一个byte类型的变量,然后赋值150,看报什么错!
6.short、int:在Java中数据类型整型short=2字节,1字节等于8位,2字节等于16位,每位有0或1两种状态,则short可以组合2^16=65536种状态,取值范围则为-32768~32767(将65536除以2平分到正负数两边),超出此范围外的数值都表示不了。
数据类型整型int=4字节,1字节等于8位,4字节等于32位,每位有0或1两种状态,则short可以组合2^32=4294967296种状态,取值范围则为--2147483648~2147483647(将4294967296除以2平分到正负数两边),超出此范围外的数值都表示不了。
7.char:在Java中char类型为2字节,即可以表示65536个字母表中的字符,标点符号和其他的一些符号(中文字符等)。在计算机中,文本是由字符组成的。Java中char类型只能表示65536个Unicode字符集,其余的字符集需要String才能表示!
8.字符集合(ASCII、Unicode):由一套用于特定用途的字符组成,例如支持西欧语言的字符集合,支持中文的字符集合。字符集合只定义了符号和他们的语意,其实跟计算机没有直接关系。现实生活中,不同的语系有自己的字符集合,例如藏文有自己的字符集合,汉文有自己的字符集合。到计算机的世界中,也有各种字符集合,例如ASCII字符集合,GB2312字符集合,GBK字符集合。还有一个其他字符集合的超集--Unicode字符集定义了几乎绝大部分现存语言需要的字符,是一种通用的字符集,来支持多语言环境(可以同时处理多种语言混合的情况)。各个国家和地区在制定编码标准的时候,“字符集合”和“字符编码”一般都是同时制定的。所以像ASCII字符集合一样,它也同时代表了一种字符的编码。
9.字符编码:是一套规则,定义了在计算机内存中如何表示字符,是字符集中的每个字符与计算机内存中字节之间的转换关系,也可以认为是把字符数字化,规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储。例如ASCII编码[你没看错,它既是一种字符集合,也是一种字符编码],定义了英文字母和符号在计算机中的表示方式,是用一个字节来表示。Unicode字符集合,有好几种字符编码方式,例如变长度编码的UTF8,UTF16等。中文字符集也有很多字符编码,例如上文提到的GB2312编码,GBK编码等。
char、unicode、string和UTF8、UTF16之间的关系描述:Java语言内部使用的就是16位的Unicode编码,从概念上讲java字符串就是Unicode字符序列,Unicode字符集合的码点(码点:指与一个编码表中的某个字符对应的代码值)可以分成17个代码级别,第一个代码级别称为基本的多语言级别,码点从U+0000到U+FFFF,即65536个码点,只有第一级别的码点可以用一个char值表示;其余的16个级别码点从U+10000到U+10FFFF,其中包含一些辅助字符,需要两个char值才能表示一个码点;Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储,二进制与16进制等可以灵活转换,只是数值的表示方式变化而已,其值的大小不变。
UTF8、UTF16即为采用什么样的规则表示所有的码点,在UTF16的编码规则中,UTF16采用不同长度的编码表示所有的Unicode码点,在基本的多语言级别,每个字符用16位表示,通常被称为代码单元;而辅助字符采用一对连续的代码单元进行编码。U+D800~U+DFFF为空闲的2048个替代区域,U+D800~U+DBFF用于第一个代码单元,U+DC00~U+DFFF用于第二个代码单元,这样的设计可以迅速的知道一个代码单元是一个字符的编码还是一个辅助字符的第一或第二部分。
同样,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
下面,还是以汉字"严"为例,演示如何实现UTF-8编码。
已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5。
通过上面的讲解希望能解答到您的疑惑,如疑惑仍然,死磕上面的概念您终会领悟贯通的!