关于从字节到整数的转换,我有点困惑。请考虑以下代码:
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是否将所有内容转换为Integer,然后再将其传递给|
运算符?为什么&0xFF
会有所作为?
答案 0 :(得分:4)
Java字节已签名(不幸的是) - 因此,当您将值提升为int
以执行按位|
时,它最终会被标记为0xFFFFFFF0
。然后用|
弄乱data[0]
。使用& 0xff
进行屏蔽将其转换为整数值240(仅0x000000F0
)。
然而,你已经遇到了问题。这段代码:
int masked = data[0] << 8 & 0xFF | data[1] & 0xFF;
应该是:
int masked = ((data[0] & 0xff) << 8) | (data[1] & 0xFF);
...否则你在班次后掩饰,这是行不通的。我添加了括号,因为我无法确定&
,<<
和|
的预定...
答案 1 :(得分:1)
它类似于已知的“谜题”
byte x = -1;
x = x >>>= 1;
System.out.println(x);
产生
-1
没有转变?这是因为在编译arithemtic / shift /比较表达式之前,javac将byte(以及short和char)提升为int或long(如果表达式中有任何long),所以它的工作方式如下
x -> int = 0xFFFFFFFF; 0xFFFFFFF >>> 1 = 0x7FFFFFF; (byte)0x7FFFFFF -> 0xFF