1

我对从字节到整数的转换有点困惑。考虑以下代码:

byte[] data = new byte[] { 0, (byte) 0xF0 };

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF; //240
int notMasked = data[0] << 8 | data[1]; //-16

因为java中的字节是有符号的,data[1]不是十进制的240,而是2的补码,-16。但是,它仍然应该是二进制的:0x11110000那么,我为什么需要这样做data[1] & 0xFF

Java 在将所有内容传递给|运算符之前是否将其转换为整数?那为什么会&0xFF有所作为呢?

4

2 回答 2

4

Java 字节是有符号的(不幸的是) - 因此,当您将值提升为 anint以执行按位|时,它最终会被符号扩展为0xFFFFFFF0. 然后搞砸了|with data[0]。掩码& 0xff将其转换为整数值 240(只是0x000000F0)。

但是,您仍然遇到问题。这段代码:

int masked = data[0] << 8 & 0xFF | data[1] & 0xFF;

应该:

int masked = ((data[0] & 0xff) << 8) | (data[1] & 0xFF);

...否则您在换班进行掩蔽,这是行不通的。我添加了括号,因为我不确定&,<<|...

于 2012-12-07T10:20:15.387 回答
1

它类似于一个已知的“谜题”

byte x = -1;
x = x >>>= 1;
System.out.println(x);

生产

-1

不换班?这是因为在编译算术/移位/比较表达式之前,javac 将 byte(以及 short 和 char)提升为 int 或 long(如果表达式中有 long),所以它的工作方式如下

x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF
于 2012-12-07T11:00:16.237 回答