Java中的代码点与代码单元

在Java中,什么是代码点与代码单元?

代码点(Code Point):在 Unicode 代码空间中的一个值,取值 U+0000 至 U+10FFFF,代表一个字符

其中U+0000到U+FFFF为基本字符,U+10000到U+10FFFF为增补字符。


代码单元(Code Unit):在具体编码形式中的最小单位。比如 UTF-16 中一个 code unit 为 16 bits,UTF-8 中一个 code unit 为 8 bits。


对应关系:

一个 code point 可能由一个或多个 code unit(s) 表示。在 U+10000 之前的 code point 可以由一个 UTF-16 code unit 表示,U+10000 及之后的 code point 要由两个 UTF-16 code units 表示。

这也是为什么Java不提倡使用char类型的原因了。

在 Java 中一个 Unicode 字符是使用 UTF-16 编码的 char 进行表示的,也就是一个 char 只能表示 U+0000~U+FFFF 的 Unicode 基本字符(BMP)。因此在 Java 中需要表示 U+10000~U+10FFFF 的字符需要使用 一对代理字符进行表示,高代理字符的范围为 U+D800~U+DBFF,低代理字符的范围为 U+DC00~U+DFFF。比如表示 U+10400 的字符需要两个 char(U+D801, U+DC00)才能表示,这时的代码点长度为 1,而代码单元长度为 2。


在Java中:

String.length()表示代码单元长度
String.codePointCount()表示代码点长度

String.chatAt(int index)表示返回代码单元
String.codePointAt(int index)表示返回代码点

测试:

/**
 * Created by N3verL4nd on 2016/11/11.
 */
public class HelloWorld {
    public static void main(String[] args){

        String str = "\u03C0 \uD835\uDD6B";
        System.out.println("str="+str+"\n"+"str.length="+str.length()+"\n"+
                "str.codePointCount="+str.codePointCount(0, str.length()));
        for (int i = 0; i < str.length(); i++){
            System.out.println("str.charAt("+i+")="+str.charAt(i));
        }
        for(int i = 0;i < str.codePointCount(0, str.length()); i++) {
            System.out.printf("str.codePointAt(" + i + ")=%c(%#4x)\n",
                    str.codePointAt(i), str.codePointAt(i));
        }
//        String str = "你好吗ABC";
//        int i = 0;
//        while (i < str.length())
//        {
//            int cp = str.codePointAt(i);
//            System.out.println(cp);
//            if (Character.isSupplementaryCodePoint(cp)){
//                i += 2;
//            }
//            else{
//                i++;
//            }
//        }
    }
}

输出:

参考:

http://www.blogjava.net/zhenandaci/archive/2009/01/05/249866.html

http://blog.csdn.net/weizhaozhe/article/details/3909079#html

http://www.letiantian.me/2015-03-02-character-encoding/


posted @ 2016-11-11 17:29  N3verL4nd  阅读(160)  评论(0编辑  收藏  举报