相关概念:
1.Java中的字符串String由字符(char)序列表示,他实现了“字符序列”接口CharSequence。
在Java中,char类型由UTF-16描述一个代码单元。
(引用Core Java第八版:In Java, the char type describes a code unit in the UTF-16 encoding.)
这里所说的Java中,说的是编译完的class文件,并非Java源代码文件,事实上,Java源代码文件的字符集格式是由我们自己定义的,比如GBK,UTF-8等。
2.在Java中字符类型由“代码单元”表示(code unit),其中又涉及到“代码点”的概念,即对应unicode中的字符编码。
我们在用String的length()方法得到字符串长度的时候,其实得到的时候代码单元的个数,如果字符串当中包含“辅助字符”,得到的length长度可能就不是我们想象中的那样了,这点很重要。要得到真正的长度,其实应该用codePointCount()方法!
3.bmp维基百科中是这么描述BMP的:基本多語言平面內定義的符號(Basic Multilingual Plane, BMP)
4.同时还有"辅助平面"的概念
注:关于bmp和辅助平面,这些概念比较抽象,也是看了好几遍的维基百科才明白的。
我的最简单理解是:编码在0-65535之间的字符属于bmp,大于65535的就属于辅助平面
5.bom(byte order mark),为了区分大小尾序,
UTF-16LE以FF FE代表,UTF-16BE以FE FF代表(
其中U+FEFF字符在UNICODE中代表的意義是ZERO WIDTH NO-BREAK SPACE,顧名思義,它是個沒有寬度也沒有断字的空白
)
关于UTF-16编码(没有包含涉及到的UTF-16LE和UTF-16BE,即大小尾序)
1)在基本多语言平面内(bmp)的字符由一个代码单元组成,也就是说包含俩字节
2)在辅助平面内的字符,由俩代码单元组成,也就是包含四个字节(这些字符很少用到)
另外:65535对应的十六进制数字为0xFFFF,他起到分界线的作用,很重要的数字。
由于UNICODE编码范围最大为0x10FFFF,因此得到辅助平面的范围:0x10000~
0x10FFFF
3)UTF-16编码的算法
a.编码在0到65535之间,也就是属于bmp的字符,直接才用本身的俩字节来表示
b.编码大于65535的,也就是辅助字符范围内的算法比较麻烦一点。
先有两个重要的数字
0xD800(二进制:1101100000000000)和
0xDC00(二进制:1101110000000000)
取字符的编码前十位和
0xD800进行
or
位运算,后十位和
0xDC00进行or位运算,得到的32位的四个字节就是该字符的编码了。
参考: