深入理解char

个人反思

Java中有Character、String、StringBuilder等用于文本处理的类,但这些类的基础都是char
以前我对char的理解总是浮于表面,知道char能表示一个字符(字母或中文字符等),也知道有Unicode编码,也知道char能转成int类型,但对char没有一个更深入的了解。这篇文章算是自己对char的一个深入总结,将以上知识点串联起来。

字符的编码

编码有两大类:Unicode编码和非Unicode编码 (了解即可)
非Unicode编码:

  • ASCII码:自然是熟悉不过的,ASCII码使用了128个字符基本表示了美国的标准字符。用了从0~127刚好128个十进制数来表示,刚好占用了7个bit位。而一个字节有8位,所以最高位设为0表示这是ASCII编码。
  • GBK码:GBK使用了两个字节来表示一个字符,其中高位字节范围是0x81~0xFE,低位字节范围0x40~0x7E0x80~0xFE。前面写到:ASCII编码最高位为0,其他编码最高位设置为1。这里需要注意的一点是:由于GBK低位编码表示范围从0x40(64)开始,所以低位编码的最高位可能为0。所以,为了区分这是GBK还是ASCII,在读入第一个字节时,如果高位为1,那么直接将下一个字节也读入进行共同解析。

Unicode编码:
这里主要介绍UTF-8
UTF-8使用可变长字节来表示一个字符,具体可参考下表[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KeK3CBwq-1644569389530)(2)]
小于128的,编码与ASCII码一样,最高位为0。其他编号的第一个字节有特殊含义,最高位有几个连续的1就表示用几个字节表示,而其他字节都以10开头。
这里举一个例子来表示一个字符的Unicode编码
通过Unicode工具查询到字符’馨’的十六进制数为99A8(39336)。按照上表的范围可知,需要3个字节进行表示(当然,这里也可以通过写出2进制,倒推出具体需要多少位)。则其二进制格式为

1110xxxx 10xxxxxx 10xxxxxx

0x99A8的二进制为

1001 100110 101000

将上面的二进制数依次填入Unicode格式中即可得到字符’馨’的UTF-8编码

11101001 10100110 10101000

char

*char本质上是一个占用两个字节的无符号正整数。*在Java内部进行字符处理时,采用的都是Unicode编码。所以char只能表示Unicode编号在65536以内的字符(存储原编号的二进制数)。超出这个范围的字符,就只有使用2个char或String、Character来进行表示。

总结

在此基础上,上文的多个知识点也就被串联了
以下是char的赋值

char a = 'A';
char b = '馨';
char c = 39336;
char d = 0x99A8;
char e = '\u99A8';

以上代码,除了a是’A’,其他的4种赋值方式表示的字符都是’馨’。

基于以上编码知识,能初步认识到乱码无非就两种情况:

  1. 解析错误:一个GBK编码的字符,用Unicode进行解析,得到的可能就是一个乱码
  2. 错误解析与编码转换:
    (1)字符串“丁香花”,本来的编码格式是GB18030,编码(十六进制)是b6a1cfe3bba8
    (2)这个二进制形式被错误当成了Windows-1252编码,解读成了"¶¡Ï㻨"(java可参考在Java中使用Windows-1252)
    (3)随后这个字符进行了编码转换,转换成了UTF-8编码,形式还是"¶¡Ï㻨",但十六进制变成了c2b6c2a1c38fc3a3c2bbc2a8
    (4)这个时候再按照GB18030解析,字符就变成了乱码形式"露隆脧茫禄篓",而且这时无论怎么切换查看编码的方式,这个结果看起来都是乱码。

PS UTF-8 编码格式补充

  • 一字节:0xxxxxxx
  • 二字节:110xxxxx 10xxxxxx
  • 三字节:1110xxxx 10xxxxxx 10xxxxxx
  • 四字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值