Java 中的字节和字符转换

2022-08-31 16:27:44

如果我把一个字符转换为,然后再转换回 ,该字符就会神秘地消失并成为其他东西。这怎么可能?bytechar

这是代码:

char a = 'È';       // line 1       
byte b = (byte)a;   // line 2       
char c = (char)b;   // line 3
System.out.println((char)c + " " + (int)c);

直到第 2 行,一切都很好:

  • 在第1行中,我可以在控制台中打印“a”,它将显示“È”。

  • 在第2行中,我可以在控制台中打印“b”,它将显示-56,即200,因为字节是签名的。200 是“È”。所以它仍然很好。

但是第3行出了什么问题呢?“c”变成别的东西,程序打印 。这是完全不同的东西。? 65480

为了获得正确的结果,我应该在第3行写些什么?


答案 1

Java 中的字符是 Unicode 代码单元,它被视为无符号数字。因此,如果您执行,则得到的值是2 ^ 16 - 56或65536 - 56。c = (char)b

或者更准确地说,字节首先转换为有符号整数,其值在加宽转换中使用符号扩展。然后将其缩小到当转换为 a 时,这又被转换为正数。0xFFFFFFC80xFFC8char65480

从语言规范:

5.1.4. 加宽和缩小基元转换

首先,通过加宽基元转换 (§5.1.2) 将字节转换为 int,然后通过缩小基元转换 (§5.1.3) 将生成的 int 转换为 char。


为了获得正确的点,首先通过使用掩码将的字节值转换为正整数,并在转换后将前24位归零:成为或小数点中的正数。char c = (char) (b & 0xFF)b2000xFFFFFFC80x000000C8200


以上是 直接解释 在 和 基元类型之间转换期间发生的情况。byteintchar

如果要对字节中的字符进行编码/解码,请使用 、 或 或 一种方便的方法,如 或 。您可以从 中获取字符集(如 UTF-8 或 Windows-1252)。CharsetCharsetEncoderCharsetDecodernew String(byte[] bytes, Charset charset)String#toBytes(Charset charset)StandardCharsets


答案 2

这对我有用: //添加导入语句

import java.nio.charset.Charset;

改变

sun.io.ByteToCharConverter.getDefault().getCharacterEncoding() -> Charset.defaultCharset()

推荐