char项目 你说你是高工char都没搞明白

来源于公众号IT烂笔头 ,

作者手艺人

1

场 景


可能很多人对Java中最简单的char类型根本不屑一顾,不就是一个字符吗?能玩出什么花来?真的是这样吗?真不一定,我见过的几个所谓的高工对char的理解可能都是在比较浅的水平。今天我就带大家从高工的角度思考这个简单的Java类型Char。

抛出问题:char如何存utf-8字符?


2

UTF-8的由来

我们知道char是占两个字节的这个大家都知道,那UTF-8是什么呢?我们见得比较多,真正能说清楚的也不见得都能做到,在谈到UTF-8,我们不得不谈下Unicode,对于有些人来说Unicode可能稍微陌生点,但是说到ASCII码估计大家都知道。


简单说明下,我们知道计算机只能识别0和1,那么如何将我们这个世界中如此众多的文字呈现或者传播呢?美国人搞了个ASCII码就是一个将英文中的字母和一些特殊符号一共128种,使用7位二进制数字一一对应起来(说白了就是符号和7位二进制数的映射表)。


计算机中每八位二进制组成一个字节,它是计算机存储的最小单位。那么我们就可以用一个字节,最高为用0占位就完全足够标识英文中的任何字母了,这样就可以将英文在计算机中进行无压力的传播啦。(举个例子:字母“A”对应的二进制数为“01000001”即十进制的41)不错!这确实解决了美国的问题,可是世界上那么多国家的不同文字字符,不全是英文字母啊,这怎么行呢?


诶?!于是Unicode诞生了,他将编号范围扩大为0x000000~0x10FFFF来将世界上绝大多数的字符一一映射起来了。(Unicode可以说是对ASCII的补充,它也是一个字符集)比如中文“马”字,对应的唯一的Unicode编号为U 9A6C(16进制的表示方式)。


注意Unicode只是规定了字符的编号,并没有说明以什么样的形式存储,你可以说直接将编号转换成二进制进行存储不就可以了吗?不错,这么做确实可以,但是会带来几个问题?

  • 如何和ASCII码区分开来,计算机无法知道三个字节表示一个字符还是三个不同的字符?
  • 英文字符只需要一个字节就能表示完,如果Unicode统一说使用三个或者四个字节表示一个字符,那么对于英文字符存储空间造成很大的浪费


所以,出现了很多中来实现Unicode编码方式,UTF-8就是其中一种,他是一种变长的编码方式,比如英文字符他只使用一个字节存储,按照不同的Unicode编号,将他们划成四个范围,分别对应使用一个、两个、三个、四个字节。


而且编码规则简单,便于计算机判断当前多少个字节表示一个字符。比如检测到当前字节以0开头,那么当前字节就对应一个字符,如果开头是“1”,那么开头有多少个连续的“1”就表示当前这个字符占用多少个字节来存储。


以上,让我们知道了UTF-8其实就是Unicode字符集的一种编码方式,它可能会占用1~4个字节。

3

回归问题


那么,回到最初的问题,char是两个字节的,那么怎么使用char类型存UTF-8编码的字符呢(可能会是3或者4个字节)?


其实,我们可以定义一个char类型的数据赋值为'庆','庆'使用utf-8编码后为:e5ba86,不错是三个字节,三个字节怎么赋值给只占两个字节的char类型变量呢?可是事实是确实可以赋值的:

char test = '庆';

确实编译器没有报错,咋回事呢?这里就是大家的误区了。其实'庆'使用UTF-16进行编码无论是大尾序utf-16BE(5E86)还是使用小尾序utf-16LE(865E)进行编码都是占用两个字节也就是一个字符的。


所以,我们要了解一个事实就是JVM中对char是使用UTF-16编码的。使用UTF-16的好处是大部分字符都能以固定两个字节存储,但是这样的坏处就是对于英文字符存储就造成浪费,但是为了解决这个问题,Java9以后对字符串做了优化,对于字符串里面都是拉丁字母或者ASCII码中的字符,不使用UTF-16编码存储,而是使用byte存储,这样可以省一部分空间。

4

发散性思考


emoji的表情""这个字符是占用几个字节呢,你可以这么赋值吗?

char emoji = '';

发现编译器会报错的,我们换成下面的字符串的方式就没有问题了:

String emoji = ""; System.out.println(emoji.length()); // 输出 2

这是为什么呢?感兴趣的读者可以去查下""这个表情的码点(Unicode中对应的值),使用UTF-16进行编码后看看有多少个字节,就知道为什么不能用char来存储了。


总结:本文看起来简单,其实讲的细节也是蛮多的。需要读者的基础知识比较扎实,对Unicode字符集,utf-8、utf-16编码都有一定的了解。


char项目 你说你是高工char都没搞明白(1)


,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页