问题引入~~

先描述一下,我最开始想不通的问题:我们知道,在java中有4类8种基本数据类型,其中一种就是字符型char,char代表一个字符,大小是2个字节,也就是2的16次方。而在UTF-8编码方式中,可能用3个字节或者4个字节来表示一个字符。那么char怎么有足够的bit位来32位或者更多的二进制呢?

其实这个问题存在一个概念上的误区,那就是关于字符集,字符编码的关系!char中保存的是字符对应的Unicode值而不是UTF-8字符编码的多个字节。

Unicode字符集和UTF-8字符编码的关系?

在 Unicode 出现之前,所有的字符集都是和具体编码方案绑定在一起的(即字符集≈编码方式), 都是直接将字符和最终字节流绑定死了,例如 ASCII 编码系统规定使用 7 比特来编码 ASCII 字 符集;GB2312 以及 GBK 字符集,限定了使用最多 2 个字节来编码所有字符,并且规定了字节 序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备 上的字节流了。

但是对于 Unicode 则不同,Unicode 字符集只是定义了字符的集合和唯一编号,Unicode 编码, 则是对 UTF-8、UCS-2/UTF-16 等具体编码方案的统称而已,并不是具体的编码方案。所以当需 要用到字符编码的时候,你可以写 gb2312,codepage936,utf-8,utf-16,但请不要写 Unicode。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用 1~4 个字节表示一个符号。 从 unicode 到 uft-8 并不是直接的对应,而是要过一些算法和规则来转换(即 Uncidoe 字符集 ≠UTF-8 编码方式)。

以【尚】字为例

java char修改编码方式 java中char采用什么编码方案_java char修改编码方式

char c1 = '尚';
        char c2='\u5C1A';

        System.out.println(c1==c2);

        运行结果为true

所以,在内存中,

char中保存的是字符对应的Unicode值而不是UTF-8字符编码的多个字节。


总结

简单来说,以【尚】字为例,当使用UTF-8字符编码,把【尚】这个字保存到磁盘中,其占用了3个字节也就是24个bit位,但当你把它赋值给char类型变量时,会按照一定的规则,从24个bit中提取出16个bit,组成一个2字节的Unicode值,将其赋值给char型变量。