在Java中将字节转换为String时会发生什么?

use*_*713 9 java string unicode byte utf-8

尝试在Java中将字节转换为String时遇到问题,代码如下:

byte[] bytes = {1, 2, -3};

byte[] transferred = new String(bytes, Charsets.UTF_8).getBytes(Charsets.UTF_8);
Run Code Online (Sandbox Code Playgroud)

并且原始字节与传输的字节不同,它们分别是

[1, 2, -3]
[1, 2, -17, -65, -67]
Run Code Online (Sandbox Code Playgroud)

我曾经认为这是由于UTF-8字符集映射为负"-3".所以我把它改成"-32".但转移的阵列保持不变!

[1, 2, -32]
[1, 2, -17, -65, -67] 
Run Code Online (Sandbox Code Playgroud)

所以我非常想知道当我调用new String(bytes)时会发生什么

Den*_*ret 9

并非所有字节序列在UTF-8中都有效.

UTF-8是一种智能方案,每个代码点具有可变数量的字节,每个字节的形式表示相同代码点跟随多少其他字节.

参考此表:

表

现在让我们看看它如何适用于您{1, 2, -3}:

字节1(十六进制0x01,二进制00000001)和2(十六进制0x02,二进制00000010)是独立的,没问题.

字节-3(十六进制0xFD,二进制11111101)是6字节序列的起始字节(在当前的UTF-8标准中实际上是非法的),但是您的字节数组没有这样的序列.

您的UTF-8无效.Java UTF-8解码器用-3Unicode代码点U + FFFD REPLACEMENT CHARACTER替换这个无效字节(也见这个).在UTF-8中,代码点U + FFFD是十六进制0xEF 0xBF 0xBD(二进制11101111 10111111 10111101),用Java表示-17, -65, -67.