回答
张老师的一个问题。下面的回答虽然油嘴滑舌,但我承认这个问题本身比较有趣,属于有关UTF-8的基础知识,值得掌握。人家布老大都说了,如果你想请教他怎么写处理32位的编码解码程序,得交钱,还是美元。可见这个知识还是很有用的。
下面是回答:
困扰大半年?是看了
Bruce Eckel的帖子后来考您的吧?连测试的例子都和布老大的一模一样。
功夫在诗外啊。与其说是Java问题,不如说是 UTF-8编码问题。有兴趣的老大们自然可以去看 RFC3629。
魔鬼出于细节啊。偏偏这句话就把细节隐藏了:"UTF-8编码转换成字符串,再将结果字符串转换成UTF-8编码的字节数组"。用这句话来问我们这些Java程序员,明显假设编码和解码是对称的。天大的误会啊:
第一个字节:0xC0 = 11000000
第二个字节:0xB1 = 10110001
根据UTF-8的编码规则,我们去掉第一个字节的110,去掉第二个字节的10,于是得到真正的UTF-8字符:000000110001(我加了两个填位子的0)。这个等于0x31(也就是ASCII的'1'啦,和代码运行结果一致)。再根据UTF-8的编码规则,0x31小于0x007F,所以我们用一个字节把它编码为0x31,和ASCII的0x31等价。既然是ASCII,当然长度也就是1了哈。
P.S., 张老师这次很激动啊。标题用感叹号,变疑问为质问,属于语文不及格的初中生和喜欢匝匝呼呼的小女生在聊天室聊天的风格(注意,俺说的是风格,无关对错)哈。
嗯,解释完了。收工。回家。
功夫在诗外啊。与其说是Java问题,不如说是 UTF-8编码问题。有兴趣的老大们自然可以去看 RFC3629。
魔鬼出于细节啊。偏偏这句话就把细节隐藏了:"UTF-8编码转换成字符串,再将结果字符串转换成UTF-8编码的字节数组"。用这句话来问我们这些Java程序员,明显假设编码和解码是对称的。天大的误会啊:
第一个字节:0xC0 = 11000000
第二个字节:0xB1 = 10110001
根据UTF-8的编码规则,我们去掉第一个字节的110,去掉第二个字节的10,于是得到真正的UTF-8字符:000000110001(我加了两个填位子的0)。这个等于0x31(也就是ASCII的'1'啦,和代码运行结果一致)。再根据UTF-8的编码规则,0x31小于0x007F,所以我们用一个字节把它编码为0x31,和ASCII的0x31等价。既然是ASCII,当然长度也就是1了哈。
P.S., 张老师这次很激动啊。标题用感叹号,变疑问为质问,属于语文不及格的初中生和喜欢匝匝呼呼的小女生在聊天室聊天的风格(注意,俺说的是风格,无关对错)哈。
嗯,解释完了。收工。回家。
更新:该了标题。利用张老师的名气赚点击。嘿嘿。