字符串成字符? (JAVA)

怎么会发生这种情况:

char a = '\uffff'; //Highest value that char can take - 65535 byte b = (byte)a; //Casting a 16-bit value into 8-bit data type...! Isn't data lost here? char c = (char)b; //Let's get the value back int d = (int)c; System.out.println(d); //65535... how? 

基本上,我看到一个char是16位。 因此,如果将其转换为byte ,为什么没有数据丢失? (转换为int后的值相同)

提前谢谢你回答我这个无知的问题。 :P

编辑:哇,发现我的原始输出实际上按预期执行,但我刚刚更新了上面的代码。 基本上,将一个字符强制转换为一个字节,然后将其强制转换为char,并保留其原始的2字节值。 这是怎么发生的?

正如trojanfoe所述,您对代码结果的混淆部分是由于符号扩展。 我会尝试添加更详细的解释,这可能有助于您的困惑。

 char a = '\uffff'; byte b = (byte)a; // b = 0xFF 

如您所述,这会导致信息丢失。 这被视为缩小转换 。 将char转换为字节“只丢弃除n个最低位之外的所有位”。
结果是: 0xFFFF -> 0xFF

 char c = (char)b; // c = 0xFFFF 

将字节转换为char被视为特殊转换 。 它实际上执行两次转换。 首先,字节是SIGN扩展的(新的高阶位从旧符号位复制)到int(正常的加宽转换)。 其次,int转换为具有缩小转换的char。
结果是: 0xFF -> 0xFFFFFFFF -> 0xFFFF

 int d = (int)c; // d = 0x0000FFFF 

将char转换为int被视为扩展转换 。 当char类型被扩展为整数类型时,它是ZERO扩展的(新的高位比特被设置为0)。
结果是: 0xFFFF -> 0x0000FFFF 。 打印时,这将给你65535。

我提供的三个链接是关于原始类型转换的官方Java语言规范详细信息。 我强烈建议你看看。 它们并不是非常冗长(在这种情况下相对简单)。 它详细说明了java将在幕后进行类型转换的内容。 对于许多开发人员来说,这是一个常见的误解区域。 如果您仍然对任何步骤感到困惑,请发表评论。

这是标志延伸 。 尝试\u1234而不是\uffff ,看看会发生什么。

java byte已签名。 这是反直觉的。 在几乎所有使用字节的情况下,程序员都希望使用无符号字节。 如果将一个字节直接转换为int,则极有可能是一个错误。

这几乎在所有程序中都能正确地进行转换:

 int c = 0xff & b ; 

根据经验,选择带符号的字节是错误的。

你机器上有些奇怪的东西。 看一下Java语言规范,第4.2.1章 :

整数类型的值是以下范围内的整数:

对于字节,从-128到127(含)

……剪掉别人……

如果您的JVM符合标准,那么您的输出应为-1