Java 将字符串编码为UTF-8字节时添加的空字符?

Java 将字符串编码为UTF-8字节时添加的空字符?,java,character-encoding,Java,Character Encoding,代码片段: public static void main(String[] args) { String s = "qwertyuiop"; System.out.println(Arrays.toString(Charset .forName("UTF-8") .encode(s) .array())); } 印刷品: [113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 0] 这似

代码片段:

public static void main(String[] args) {
    String s = "qwertyuiop";
    System.out.println(Arrays.toString(Charset
       .forName("UTF-8")
       .encode(s)
       .array()));
}
印刷品:

[113, 119, 101, 114, 116, 121, 117, 105, 111, 112, 0]
这似乎是因为,在java.nio.charset.CharsetEncoder类中,对于UTF-8,averageBytesPerChar变量似乎是1.1。因此,它分配11个字节,而不是10个,并且,如果输入字符串只包含好的旧单字节字符,我最终会得到那个奇怪的空字符

我想知道这是否在任何地方都有记录

本页:

对这种行为一无所知

另外,我是否正确地理解了,在任何情况下,上面的代码片段最好替换为:

s.getBytes(StandardCharsets.UTF_8)
我从它的源代码中看到,为了避免那些空字符,它还会修剪结果

那么,java.nio.charset.charset的编码(字符串s)应该是什么呢?

问题不在于
charset.encode()
,而在于
Buffer.array()
。 如果您打印了
Charset.forName(“UTF-8”).encode
,您会发现输出是

java.nio.HeapByteBuffer[pos=0 lim=10 cap=11]
ByteBuffer具有限制10(字符串长度)和容量11(缓冲区的总分配大小)。如果更改编码,则限制和容量可能会有更大的变化,例如:

System.out.println(Charset.forName("UTF-16").encode(s));
// java.nio.HeapByteBuffer[pos=0 lim=22 cap=41]
// (2 extra bytes because of the BOM, not null-termination)
当您选择时,它将返回整个备份阵列,因此即使超出限制的内容也将被包括在内

提取Java字节数组的实际方法是:

这看起来一团糟?因为“nio”的意思是NI/O。创建缓冲区类型是为了方便地包装C数组。它使得与本机代码的交互(如读/写文件或发送/接收网络数据)非常高效。这些NIOAPI通常直接使用
缓冲区
,而不在缓冲区之间构建任何
字节[]
。如果只使用
缓冲区
,中间两行不需要存在:)


如果整个操作都在Java中,是的,只需调用
s.getBytes(StandardCharsets.UTF_8)
如果您只想查看编码为UTF8的字符串的字节数组,只需使用方法即可。它可能看起来像这样:

String hello = "qwertyuiop";   
byte[] helloBytes_UTF_8 = hello.getBytes(StandardCharsets.UTF_8);
您将看到每个字符有2个字节。您的输出符合
标准字符集.ISO_8859_1
字符集。如果您想更多地使用不同的编码,那么我建议使用一个带有一些UTIL的小型开源库,其中一个允许您将字符串共同转换为UNICODE(UTF-8)表示形式并返回。本文介绍了该库以及如何使用它。您还可以下载源代码和javadoc。特别要查找段落“字符串Unicode转换器””。使用该类,您将把字符串
“qwertyuiop”
转换为:
“\u0071\u0077\u0065\u0072\u0074\u0079\u0075\u0069\u006f\u0070”
\u符号后的每四位数字表示两个字节(一个字符),以十六进制表示

String hello = "qwertyuiop";   
byte[] helloBytes_UTF_8 = hello.getBytes(StandardCharsets.UTF_8);