Java字符串“hello”在getBytes(“UTF16”)时有12个字节?
我预计,当一个java字符存储为“UTF-16”时,每个字符使用2个字节,所以“hello”应该使用10个字节,但以下代码:
String h = "hello";
System.out.println(new String(h.getBytes("UTF-16"), "UTF-16").length());
System.out.println(new String(h.getBytes("UTF-8"), "UTF-8").getBytes("UTF-16").length);
将打印“5 12”
我的问题是:
(1)我希望第一个println应该像我提到的那样得到“10”。但为什么是5
(2)对于第二个println,我试图获取字节,首先是“UTF-8”,然后是“UTF-16”。我想也应该是10。但实际上是12
我用的是MAC电脑,我所在的地区是香港。你能解释一下节目中发生了什么,以及“512”是如何产生的吗
非常感谢
# 1 楼答案
取一个5个字符的字符串,使用UTF-16编码将其编码为字节
然后通过(正确地)解码UTF-16中的字节来创建一个新字符串,这将再次生成一个由原来的5个字符组成的新字符串
这部分代码:
实际上是不可操作的。复制字符串是一种相当昂贵的方法。使用UTF-8作为编码方案将字符串编码为字节,然后通过解码UTF-8编码的字节来创建新字符串
因此,有效地说,你正在这样做:
额外2字节的原因是UTF-16编码将BOM(字节顺序标记)作为第一个(2字节)代码单元
有关更多信息,请阅读"UTF-8, UTF-16, UTF-32 & BOM"上的Unicode常见问题解答
# 2 楼答案
您是在
String
上调用length()
,而不是在byte[]
上调用。因此,这将为您提供字符中字符串的长度(至少只要我们停留在Unicode基本多语言平面上,当您有需要可变长度编码的字符时,即使在UTF-16中,这也会很不幸地发生故障)一旦你有了一个字符串,用什么编码来创建它就无关紧要了
length
总是以字符的形式给出如果您使用UTF-16将其转换为
byte[]
,您可能会理所当然地预期10(对于五个字符乘以每个两个字节)实际上是12,这是因为包含了字节顺序标记