首先回答题目:Java中关于Char存储中文到底是2个字节还是3个还是4个?
答案是:2个字节
原因:一个Java的char类型表示一个utf-16编码的代码单元,也就是两个字节。
在Unicode的设计之初,人们认为两个字节的代码宽度足以对世界上各种语言的所有字符进行编码,在1991年发布的Unicode1.0,当时仅用了65 536个代码值中不到一半的部分。
所以在设计Java时决定采用16位的Unicode字符集。也就是说当时所有你可以在Unicode编码表上找到的Unicode码点都可以用一个char类型表示。
但是不可避免的事情发生了,Unicode字符超过了65 536个(主要原因是增加了大量的汉语、日语、韩语),已经超过了2个字节的最大表示范围。
所以对于超过的部分只能使用两个char来表示一个字符。其中U+D800 ~ U+DBFF用于第一个代码单元,U+DC00 ~ U+DFFF用于第二个代码单元。这样java也可以很迅速的知道这个char是代表一个字符的编码,还是一个字符的第一部分或者第二部分。
对于需要用两个char来表示的字符,你单拿出任何一个char来看都是没有意义的,他们也不会映射任何Unicode的字符集,属于保留的空闲区域。当然也正是这样保留区域的设计才使得变长编码变得可能。
所以你这句话“能不能理解为在BMP范围内的中文Char是2个字节,超过该范围的中文在内存中占4个字节?“
应该是在BMP范围中的字符使用一个char储存,超过BMP的部分使用两个char来表示。
char就是char,永远是两个字节(但是在内存里是多少这个我也不清楚),char真实的含义是描述了UTF-16编码中的一个代码单元,而不是一个字符。