与0xff进行逐位AND运算很重要?

在这段代码中,与0xff进行逐位AND运算实际上是否意味着返回相同的值?

byte[] packet = reader.readPacket(); short sh; sh = packet[1]; sh &= 0xFF; System.out.print(sh+" "); 

奇怪的是,如果不包括ANDing,我得到-1,但是当包含255时可以解释原因吗?

正如我所看到的,0xff只是1111 1111.不是吗?

是的, 0xff只是1111 1111 。 但这是尝试显示无符号字节值,即使在Java byte已签名。 对于有符号byte ,值0xff-1 ,但short 255

当读取byte0xff ,打印该值将产生-1 。 所以它被分配给一个具有更大范围的short并且可以存储通常溢出为负数的byte值作为一个byte作为正整数,例如144作为byte0x90 ,或-112,但它可以正确存储为144作为short

因此, byte-1被分配给short 。 但这又做了什么? 进行原始扩展转换,并对负值进行符号扩展。 所以1111 1111变成了11111111 11111111 ,仍然是-1 ,但这次是short

然后使用位掩码0xff00000000 11111111 )再次输出最后8位:

  -1: 11111111 1111111 0xFF: 00000000 1111111 ====================== 255: 00000000 1111111 

这只是获取无符号byte值的一种方法,通过将其转换为short ,然后屏蔽byte的原始位,将其显示为无符号值。

一个byte的范围是-128到127.这意味着某些值是负数。 这是设置最高位的所有值。 所以(byte) 0xFF是-1。 当你使用符号扩展使其成为有符号的短路时,它变为(short) 0xFFFF ,它为-1作为短路。 当您屏蔽它时,它会切断扩展位,并将该字节视为无符号位置。


除非您的代码与问题中的代码不同,否则不会得到-1。

 for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { short s = b; s &= 0xff; System.out.println(b + " & 0xFF = " + s); } 

版画

 -128 & 0xFF = 128 -127 & 0xFF = 129 .... -2 & 0xFF = 254 -1 & 0xFF = 255 0 & 0xFF = 0 1 & 0xFF = 1 ... 125 & 0xFF = 125 126 & 0xFF = 126 

(假设两个地方的补充)两件事:

  1. 字节是有符号的,因此一个字节中的0xff等于-1。
  2. 当从较小的数据类型转换为较大的数据类型(在这种情况下,从一个byte到一个short )时,保留该 。 所以, sh = packet[1]会将sh设置为-1 ,即0xffff

点#2的事情是,“额外”位用1s填充,以便在原始值为负时保持该值。 与0xff进行0x00ff背后的想法是sh现在包含0x00ff ,现在删除了那些“额外”1。