本人刚刚开始自学Java,如果下面的叙述有什么错误,请大家多多包涵。
    《Java 核心技术 卷1》上关于代码单元和代码点的地方有一段解说,大意如下:用length方法可以得到该string的代码单元数,比如:
    String greeting = "Hello";
    int n = greeting.length(); // is 5 
用codePointCount方法可以得到该string的真正长度(原文是true length),也就是代码点数,比如:
    int cpCount = greeting.codePointCount(0, greeting.length());
    我自己试了一下,greeting = "中文"的时候,length和codePointCount得到的结果都是2,greeting = "English"的时候,
length和codePointCount得到的结果都是7,也就是说,length和codePointCount方法的效果一样?可是我觉得书上那段话好像不是这个意思啊……不明白……
    另外,书上还有一段,大意如下:String sentence = "Z is the set of integers";
那么char ch = sentence.charAt(1);不会返回一个空格,而是Z的第二个代码单元(原文是the second code unit of Z),如果要避免这个问题,就不要使用char类型, 因为它太low-level。
于是我又试了一下:
sentence = "Z is";
char ch = sentence.charAt(1);
结果返回的就是空格……囧……完全搞不明白了,请大家不吝赐教~~

解决方案 »

  1.   

    一般不需要考虑代码单元的长度值,可以简单地认为其与代码点的长度是一样的。只有增补字符,即代码点为 U+10000~U+10FFFF 的字符,这是 Unicode 5.0 中新增的代码点字符。在 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。
      

  2.   

    public class Main {    public static void main(String[] args) {
            char[] chs = Character.toChars(0x10400);
            System.out.printf("U+10400 高代理字符: %04x%n", (int)chs[0]);
            System.out.printf("U+10400 低代理字符: %04x%n", (int)chs[1]);        
            String str = new String(chs);
            System.out.println("代码单元长度: " + str.length());
            System.out.println("代码点数量: " + str.codePointCount(0, str.length()));
        }
    }
      

  3.   

    这里API和源码例子
    一个英文的,一个翻译的:
    http://apicode.gicp.net/class.do?api=selectByfatherIndex&father=255
    http://apicodecn.gicp.net/class.do?api=selectByfatherIndex&father=255
      

  4.   

    差不多明白了,我…好像小看Unicode了……
    原文中不是这个‘Z’,是一个特殊符号,多半就是增补字符了吧,我打不出这个字符,还以为用全角的字母也是一样,看来还是我愚钝了……
    总之谢谢大家~