Java中char是如何储存那么多汉字的
char: The char data type is a single 16-bit Unicode character. It has a minimum value of ‘\u0000’ (or 0) and a maximum value of ‘\uffff’ (or 65,535 inclusive).
char:char数据类型是一个16位的Unicode的字符。它的最小值是‘\u0000’(或者0),最大值是’\uffff’(或者65535(包含))。
那么问题来了我们中华文化博大精深,源远流长,汉字文化更是冠绝古今,据不完全统计至少有十万字以上。那65535是如何存储的下这么多汉字的呢?
我做了以下测试:
char ch = (char)65535;
System.out.println(ch);
结果打印出来了?(问号)
接着我又打印了
char ch = (char)65536;
System.out.println(ch);
发现编译没有错误,并且打印出来空值
然后我又把数字继续扩大
char ch = (char)85535;
System.out.println(ch);
编译没有错误,打印出来了丠(qiū)。
因为上面我用了强制类型转换,我们看看这些超过65535的数实际上是多少
char ch = (char)65536;
int a =ch;
System.out.println(a);
char ch1 = (char)85536;
int b =ch1;
System.out.println(b);
结果出来是0和20000。可见它还是在65535之内。
当我们试着这样做的时候
char ch = 85535;
System.out.println(ch);
就会出现编译错误。
还是那个问题,char如何储存那么多个汉字,答案是最大就只能储存65535个
我也曾试着找一些65535以外的汉字来实验,却发现根本打不出来这些字比如:乙乙(两个乙),派去掉水,等等。连小岳岳今年春晚说的瓩(千瓦)都在65535内(为29929)。
此外java 用Unicode 进行编码,虽然utf-8在编码时会占有3个字节,但是不能因此论证char的储存时会占用3个字节(可能更多),char 储存时占用两个字节。
最后还有值得注意的是,我们在对char进行运算的时候它会自动提升为int 类型。
那么char是如何储存那么多的汉字(此外还有日语,韩语等)的呢?
首先一定要记住char数据类型是一个16位的Unicode的字符。
我们都知道java是用Unicode的进行编码的,那我们首先了解一下Unicode编码。
Unicode
在Unicode编码出现前其实已经出现了很多的编码:美国的ASCll编码(我们最为熟知的),西欧语言的ISO 8859-1,俄罗斯的KOI-8,中国的GB 18030等等。因为标准不同,在使用的时候产生了很多的问题。这个时候继续一种编码一统江湖,Unicode的编码应用而生。
在1991年年发布了Unicode1.0,仅占用65536个代码值中的不到一半,而在设计Java时决定采用16的位的Unicode字符集(当时8位其实已经够用),这样会比较用更多的添加和改进空间。
可是万万没想到,在没有过多久,因为汉语,日语韩语等文字的加入(中华文化博大精深)Unicode 的字符很快就超过了65536个。这个时候char的16位早以不足满足描述所有的Unicode的字符了。
下面简述一下Java是如何解决这个问题的:从Java SE 5.0 开始。码点指一个字符代表的字符码,在Unicode的标准中以16进制书写,并加上前缀U+,如U+0041就是A的码点。然后所有的字符集又被划分为17平面,(编号为0-16),第一个是基本的多语言级别,其余为辅助级别。在基本的多语言级别是使用最为广泛的字符,代码点从U+0000到U+FFFF每个平面又65536个码点。
UTF-16
简单的了解了Unicode的编码之后,我们在聊聊最早的Unicode编码——UTF-16编码方式,UTF-16的编码方式源于USC-2(想了解可以去了解一下),码点直接映射字符编码。这种编码方式事早期的UTF-16只能覆盖基本的多语言级别。随着字符的不断增多,辅助级别的出现这种方式无法满足需求。
解决方法:
- 基本多语言级别用固定的两个字节来编码,称为代码单元。
- 辅助语言平面采用代理对对其编码:用基本多语言平面里的两个未被定义的代码单元合起来对辅助字符来编码,这样所有的编码基本落入基本的多语言级别的空闲之中,比如:我们有一个码点是U+1D546(大于65535),它是用U+D835和U+DD46来表示。
- Java中,char类型的描述了UTF-16编码中的一个代码单元。
后来又有UTF-8,UTF-32出现,更为方便了编码的方式。
最后想说前辈真的是很有智慧啊。