System.out.println(“一“);包含的编码知识-创新互联

最近发现一直对java默认的utf-8编码存在疑问,于是我想从控制台打印"一"入手,挖掘一下整个过程。如下图

成都创新互联公司咨询电话:13518219792,为您提供成都网站建设网页设计及定制高端网站建设服务,成都创新互联公司网页制作领域10多年,包括三轮搅拌车等多个领域拥有多年的网站设计经验,选择成都创新互联公司,为网站锦上添花。

开始debug,utf-8在编码汉字的时候用的三个字节,下图也能看出来。三个值为负数是因为每个字节对应的10进制数都大于128而越界了

我们再把负数转换成对应的正的10进制数,具体方法就是跟0xff作“&”运算,

分别得到228(11100100),184(1011 1000),128 (1000 0000)。

utf-8编码汉字三个字节的格式就是1110XXXX 10XXXXXX 10 XXXXXX ,取出下划线部分就是汉字“一”对应的真实二进制数字100111000000000(15位)

计算下

再看下19968对应的字符

验证也是对的,证明了我的结论。

几个关键要点:

1、utf-8编码汉字是三个字节,格式是前面说的那个格式,为什么要定义成这样的格式其实很好理解,编码后成这样,解码的时候直接取出x号对应的部分,直接就能找到整个字节序真正包含要传输表达的字符

2、byte数组在存放大于128的数字时会越界,然后就是负数存放了,后面得到具体的数值就是“&0xff”得到对应的正数

拿-127举例

-127的二进制为:11111111(由于是负数,所以符号位为1),
存储到计算机需要进行补码,正数补码后为原本的数组,负数补码为除符号位外,都进行取反操作,补码后,二进制为:10000000,
转换int需要补齐32位,所以变为11111111 11111111 11111111 10000000,(正数补0,负数补1)
由于byte不需要高24位,所以需要 & 0xff进行清零,变为00000000 00000000 00000000  10000000,进行+1操作,二进制为:00000000 00000000 00000000 10000001,
这里10000001并不是负数,由于要转换为int类型,int为32位,所以最高位为0,
转换为十进制后,就是129。

后续:理解了编码的原理就能理解乱码的问题了,如果一段文本经utf-8编码的二进制流后经其他编码解码时,由于解码的格式跟utf-8不同,每次取的二进制长度都不一样,整个二进制流就会乱掉,于是就乱码了。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网页题目:System.out.println(“一“);包含的编码知识-创新互联
文章出自:http://myzitong.com/article/dgpcii.html