有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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”是如何产生的吗

非常感谢


共 (2) 个答案

  1. # 1 楼答案

    (1) I expected that the first println should get "10" as I mentioned. But why 5?

    取一个5个字符的字符串,使用UTF-16编码将其编码为字节
    然后通过(正确地)解码UTF-16中的字节来创建一个新字符串,这将再次生成一个由原来的5个字符组成的新字符串

    (2) For the second println, I am trying to getBytes for it first as "UTF-8" then as "UTF-16". I suppose it should also be 10. But actually it's 12.

    这部分代码:

        new String(h.getBytes("UTF-8"), "UTF-8")
    

    实际上是不可操作的。复制字符串是一种相当昂贵的方法。使用UTF-8作为编码方案将字符串编码为字节,然后通过解码UTF-8编码的字节来创建新字符串

    因此,有效地说,你正在这样做:

        "hello".getBytes("UTF-16").length
    

    额外2字节的原因是UTF-16编码将BOM(字节顺序标记)作为第一个(2字节)代码单元

    有关更多信息,请阅读"UTF-8, UTF-16, UTF-32 & BOM"上的Unicode常见问题解答

  2. # 2 楼答案

    I expected that the first println should get "10" as I mentioned. But why 5?

    您是在String上调用length(),而不是在byte[]上调用。因此,这将为您提供字符中字符串的长度(至少只要我们停留在Unicode基本多语言平面上,当您有需要可变长度编码的字符时,即使在UTF-16中,这也会很不幸地发生故障)

    一旦你有了一个字符串,用什么编码来创建它就无关紧要了length总是以字符的形式给出

    如果您使用UTF-16将其转换为byte[],您可能会理所当然地预期10(对于五个字符乘以每个两个字节)实际上是12,这是因为包含了字节顺序标记