byte[] byteArray = Charset.forName("UTF-8").encode("hello world").array();
System.out.println(byteArray.length);
为什么上面这行代码打印的是12,而不是11呢?
byte[] byteArray = Charset.forName("UTF-8").encode("hello world").array();
System.out.println(byteArray.length);
public final ByteBuffer encode(CharBuffer in)
throws CharacterCodingException
{
int n = (int)(in.remaining() * averageBytesPerChar());
ByteBuffer out = ByteBuffer.allocate(n);
...
根据我的调试器显示,UTF_8$Encoder
的averageBytesPerChar
为1.1
,输入的String
有11
个字符。11 * 1.1 = 12.1
,在计算时代码将总数强制转换成int
类型,因此ByteBuffer
的结果大小为12
。ByteBuffer
,这是缓冲区的容量(实际上由于可能进行切片而不是缓冲区使用的字节数)。这有点像malloc(10)
可以自由地返回32字节内存。System.out.println(Charset.forName("UTF-8").encode("hello world").limit());
这是11(如预期)。
.length
将是您要求的长度(这在Java规范中有说明)。在这种情况下,encode()
并没有说明它会做什么,只是返回一个带有您请求的编码字符的ByteBuffer
。其他人深入研究了它,发现这是一项实现细节,因此这种行为甚至会在JVM版本和实现之间有所不同。 - David Ehrmannimport java.nio.charset.*;
public class ByteArrayTest {
public static void main(String[] args) {
String theString = "hello world";
System.out.println(theString.length());
byte[] byteArray = Charset.forName("UTF-8").encode(theString).array();
System.out.println(byteArray.length);
for (int i = 0; i < byteArray.length; i++) {
System.out.println("Byte " + i + " = " + byteArray[i]);
}
}
}
结果:
C:\JavaTools>java ByteArrayTest
11
12
Byte 0 = 104
Byte 1 = 101
Byte 2 = 108
Byte 3 = 108
Byte 4 = 111
Byte 5 = 32
Byte 6 = 119
Byte 7 = 111
Byte 8 = 114
Byte 9 = 108
Byte 10 = 100
Byte 11 = 0
该数组以空字符结尾,就像任何良好的C字符串一样。
(但显然真正的原因是不稳定的方法array。除非非常小心,否则它可能不应在“生产”代码中使用。)