日期:2014-05-20  浏览次数:20675 次

代码点、代码单元、辅助字符问题
'java字符串是有char序列组成。'问:这个命题是否成立?
常用的Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。
代码单元是什么?代码点是什么?
Java code
public static void main(String[] args) {
        String str = "中文aA";
        for(int i=0;;){
            if(i<str.length()){
                int cp = str.codePointAt(i);
                System.out.println((char)cp +"--"+ cp);
                if(Character.isSupplementaryCodePoint(cp)){
                    i += 2;
                }else{
                    i += 1;
                }
            }else{
                break;
            }
            
        }
        
    }

运行结果:
中--20013
文--25991
a--97
A--65

41在什么情况下表示A?

------解决方案--------------------
41在什么情况下表示A?

0x41->65->A
------解决方案--------------------
不是任何情况下 0x41 都能代表 A,要看字符集和前一个码是什么,有可能 0x41 只是某个双码或三码字符的后半部分。

“java字符串是由char序列组成”这个我认为基本正确。
------解决方案--------------------
探讨

引用:

不是任何情况下 0x41 都能代表 A,要看字符集和前一个码是什么,有可能 0x41 只是某个双码或三码字符的后半部分。

“java字符串是由char序列组成”这个我认为基本正确。

嗯,跟编码格式有关系,是应该这么理解。
一个字符就是一个代码单元(特殊字符:多个代码单元),
代码点:就是表示这个字符的某种编码格式下 对应的那个编码(16进制)。
……

------解决方案--------------------
UNICODE共定义了0x10FFF也就是1,114,111个代码点,如果每个代码点与一个字符定义的话,最多可以包容一百多万个字符。但是目前只用了一部分,也就是说有一部分位置(代码点)被占了。
你看到的
中--20013
文--25991
a--97
A--65

数字就是表示的这些被占的位置(编号)
代码单元是跟具体编码方式相关的概念,比如UTF-32,就是用固定的32位(3字节)作为一个代码单元,而UTF-8则是用1个字节~6个字节作为一个代码单元,因为不定长,所以必须有些约定,如3字节的时候,一定是1110 XXXX 10XX XXXX 10XX XXXX ,实际可用的位数为4+6+6=16位,相当于2个字节。

汉字在UTF-8里面是3字节,比如“中”,代码位是20013,那么16进制是0x4E2D,二进制是100111000101101
你把这16位对应插入前面的X上,就是“中”的UTF-8码了。