code point & code unit
Unicode
是世界通用的字符编码标准。它包括字符集(包含来自世界各国各地的语言、文字)和编码方案(将每个字符唯一映射到一个二进制编码);比如:总共有 A-Z[字符集] 26个字符,使用0-25来进行编码,即A-0,B-1...[映射关系]。
这样以后,0-25每个编码都是一个code point,即码字;如何将这些码字在计算机中表示?[这里我们只是一个很简单的例子,现实中的字符集数量远远大于26,可能需要多个字节序列才能表示。因此就存在在计算机中如何表示的问题]。根据表示方法的不同,又区分为我们常见的UTF-8、UTF-16和UTF-32编码方式。
- UTF-8:使用变长的字节序列来表示字符;某个字符(对应一个code point)可能使用1-4个字节才能表示;这样1个字节就是一个code unit,即代码单元。代表最小的可用来识别一个合法字符的最小字节数;
即一个code point可能由1-4个code unit组成,code unit为一个字节
; - UTF-16:使用变长字节序列来表示字符;某个字符(对应一个code point)可能使用2个或者4个字符来表示;这样2个字节就是一个code unit;因为2个字节序列是最小的能够识别一个code point的单位;
即一个code point可能由1-2个code unit组成,code unit为2个字节
; - UTF-32:定长的4个字节表示一个字符;一个code point对应一个4字节的序列,这样4个字符数就是一个code unit。
即一个code point由1个code unit组成,code unit为4个字节
;
A Unicode code unit is a bit size used by a particular Unicode encoding.For example UTF-8 has a code unit size of 8 bits and UTF-16 has 16 and UTF-32 has 32.To represent a character (i.e. a code point, which is a Unique integer assigned to each character) one or many code units may be required depending on the encoding.Java uses UTF-16 and this means the code unit size is 16 bits. Unicode has over 1 million code points (10FFFF+1 in hex). 16 bits can represents only FFFF+1 code points. (This range is called the BMP (Basic Multilingual Plane. It contains all the commonly used character in the world and some more).So to represent code points outside the BMP the UTF-16 encoding specifies surrogate pairs. For this two special ranges are defined within the BMP. In UTF-16 any character outside the BMP is represented by two 16 bit code units in this range. (In fact surrogate characters are defined only for UTF-16). Now it should be clear that certain characters may require two code units in UTF-16.So counting 16 bit code units will not yield the correct "length of characters". String.length() returns the number of code units in the String.Since 1.5 you can use codePointCount(int beginIndex, int endIndex) to get the length of the characters. It will count a surrogate pair as one character.
Java中的String类
Java JVM中的String类使用的是UTF-16编码方式。
String.length():方法返回的是字符串中char的字符个数;注意每个字符为2字节长度。
String.codePointCount():方法返回字符串中的码字个数。一个码字即对应一个Unicode字符。可能为2个字节长度或者4字节长度的。
以上两个方法的返回值可能是不相等的。如果字符串中仅包含基本多语言平面(BMP)的Unicode字符,则两者值相等。否则code point count值是小于length的,因为一个不是BMP的字符,需要两个char(一个代理对,包括前导代理和后尾代理构成)来表示。
char String.charAt(index):方法返回index位置的字符,注意该index取值是基于length方法的。
int String.codePointAt(index):方法返回index位置的码字。
以上两个方法一个返回char,一个返回int,两者可能是不相同的。也是因为超出BMP范围的字符需要两个char来表示。