Java、Android面试(1):Java中的char是2个字节,如何存UTF-8字符?

关键词: char,UTF-8

考察内容
熟悉Java char和字符串
了解字符的映射和存储细节
横向对比其他语言

java中的char是用2个字节进行存的,
UTF-8可能是1~3个字节。

例如:
char test = '庆'
是用2 个字节进行存储的。
而它的UTF-U字节是e5ba86,是3个字节。

剖析
char是什么?UTF-8是什么?占几个字节?和Unicode什么关系?

char里面存的是什么?
System.out.println(Integer.toHexString(test));
打印出来的0x5e,0x86就是Unicode的码点。

Unicode是字符集,ASCII码也是字符集。

字符集完成字符到整数的映射:
(字符) =》 码点
字符集不是编码。

如何存储字符:
字符(人类认知) -> char(字符集) -> byte(计算机存储)
编码:UTF-8


UTF-8与UTF-16的区别:
UTF-8最小的单位是1个字节,UTF-16最小的单位是2个字节。
也就是说,如果这个字符是a,a对应65,它实际上是用ASCII码,也就是7个比特就可以表示。
但是在UTF-16里面也是需要2个字节的。
Java char中存的是UTF-16。

如果把字符换成中文:
类似于“中”字,占1个char就可以了,也就是2个字节。同样是用UTF-16。

如何存储字符:
byte[] bytes= "中".getBytes("utf-16");
System.out.println(bytes.length);
for(byte b : bytes){
    System.out.print(Integer.toHexString(Byte.toUnsignedInt(b)));
    System.out.print("");
}
结果:
4
fe ff 4e 2d
其中fe ff是字节系列标志。不是代表的真正的内容,而只是让读取这个数据的人知道字节序是什么。

触类旁通:Python2的字符串
# 没问题
byteString = "I'm a byte string."

# 例如utf-8,字面量会用utf-8编码成字节存入字符串
# coding = utf-8
byteString = "中国" # .py文件中存放的是UTF-8编码后的字节。
unicodeString = u"中国" # .py文件中存放的是UCS2(~UTF-16)编码后的字节。

Python是解释执行的,源文件与执行时内存中字符串内容一致。
javac指定编码将字符串统一转为MUTF-8(调用这个命令的时候需要给个encoding的参数)

byte[] byteString= "中".getBytes("utf-8"); 对应于 byteString = "中国"
String unicodeString = "中国"  对应于  unicodeString = u"中国"
unicodeString可以调用encode(),byteString得decode().

让人迷惑的字符串长度:
String emoji= "emoji"  //emoji代表QQ表请
System.out.println(emoji.length());
//我们会认为是1,因为看到的是1 ,但不是这样的。

python<=3.2:
String emoji= u"emoji"  //emoji代表QQ表请
print(len(emoji))
结果都为2
python>=3.2:
结果等于1.

Java 9并没有改变字符串长度和字符数不一致的情况。
但是对拉丁(Latin)字符的存储空间做了优化。
字符串长度 != 字符数


题目结论
java char不存UTF-8的字节,而是UTF-16的.
Unicode通用字符集占2个字节,例如“中”.
Unicode是扩展字符集需要用一对char来表示,例如“emoji”
Unicode是字符集,不是编码,作用类似于ASCII码。
Java String的length不是字符数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醒不了的星期八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值