57

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

这是代码:

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 行写什么?

4

3 回答 3

78

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

或者更准确地说,首先将字节转换为有符号整数,其值在扩展转换中0xFFFFFFC8使用符号扩展。这反过来又缩小到0xFFC8当转换为 a 时char,它转换为正数65480

从语言规范:

5.1.4。扩大和缩小原始转换

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


要获得正确的点char c = (char) (b & 0xFF),首先使用掩码将字节值转换为b正整数200,转换后将前 24 位清零:0xFFFFFFC8变为0x000000C8或十进制的正数200


byte以上是对,intchar原始类型之间转换过程中发生的情况的直接解释。

如果要对字节中的字符进行编码/解码,请使用、Charset或一种方便的方法,例如或。您可以从.CharsetEncoderCharsetDecodernew String(byte[] bytes, Charset charset)String#toBytes(Charset charset)StandardCharsets

于 2013-07-28T20:45:18.783 回答
0

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

import java.nio.charset.Charset;

// 改变

sun.io.ByteToCharConverter.getDefault().getCharacterEncoding() -> Charset.defaultCharset()
于 2022-03-02T05:46:35.637 回答
-2

new String(byteArray, Charset.defaultCharset())

这会将字节数组转换为 java 中的默认字符集。它可能会抛出异常,具体取决于您为 byteArray 提供的内容。

于 2019-03-29T03:44:18.867 回答