Unicode in Java
Java代码使用Unicode字符集编写,在编译时Java程序里的Unicode字符会被逐一转换成token。
??Java SE各版本使用的Unicode标准是不同的,当前SE版本使用的具体是哪个版本的Unicode标准,可以在类
Character
里找到
Unicode标准创建时,每个字符使用固定的16位字符进行编码。随着对各种语言的扩展支持,Unicode字符的编码开始超过16位。
当下合法的Unicode编码从
U+0000
到U+10FFFF
码元(code unit):一个16位的编码,如0x1234
码点(code point):一个Unicode字符的编码,如U+10FFFF
补充字符(supplementary characters)是指那些码点超过U+FFFF
的字符
为了也能只用16位编码表示这些补充字符,Unicode标准定义了UTF-16编码格式
?? 不要混淆Unicode字符集,UTF-16编码方式的概念
UTF-16编码:
-
对于补充字符,使用一对16位的码元来表示
第一个16位码元来自
U+D800
到U+DBFF
,第二个16位码元来自U+DC00
到U+DFFF
-
对于编码在
U+0000
到U+FFFF
的普通字符,它的码元和码点是一样的
?? 因此在Java中,语义字符的确切名称叫做UTF-16码元(code unit),一个Unicode字符的确切名称叫做码点(code point)
码元和码点示例
public static void main(String[] args) {
String wang = "hi王??";
/* .length()返回码元的数量, .charAt()返回索引上的码元对应的字符 */
for (int i = 0; i < wang.length(); i++) {
/* 依次输出 h 68, i 69, 王 738b, ? d83d, ? dc0d */
System.out.println(wang.charAt(i) + " " + Integer.toHexString((char) wang.charAt(i)));
}
/* .codePointCount()返回码点的数量, .codePointAt()返回索引上的码点对应的字符 */
for (int i = 0; i < wang.codePointCount(0, wang.length()); i++) {
/* 依次输出 h 67, i 69, 王 738b, ?? 1f40d */
int codePointAt = wang.codePointAt(i);
String str = new String(Character.toChars(codePointAt));
System.out.println(str + " " + Integer.toHexString(codePointAt));
}
}