buff.getInt()和0xffffffffL是一个身份?

use*_*937 2 java bytebuffer bit-manipulation

这是我一直在关注的一些代码:

public static long getUnsignedInt(ByteBuffer buff) {
    return (long) (buff.getInt() & 0xffffffffL);
}
Run Code Online (Sandbox Code Playgroud)

有没有理由这样做buff.getInt() & 0xffffffffL(0xffffffffL在32个最低有效位中有32位1)?在我看来,结果将永远是buff.getInt().

awk*_*ksp 8

简而言之,这是因为该方法需要将signed int(所有Java int都是)转换为无符号数量.

如果你只是做(long) buff.getInt(),然后buff.getInt()回来-1,你最终会得到-1.这是签名数量 - 而不是该方法应该返回的数量.

所以该方法的作用是强制buff.getInt()通过AND int位来取无符号0x00000000FFFFFFFF.这有效地将签名的位"重新解释" int为无符号int(实际上是有符号的long,但是只有低32位才会被设置,它作为无符号int),产生所需的结果.

例如,(为了简洁起见,使用字节).

buff.getInt()是真的buff.getByte(),然后回来-1 == 0xFF

尝试将其投射到一个int,你最终会0xFFFFFFFF- 但仍然-1,由于符号扩展的魔力.

但是,使用0xFF,并且最终得到0x000000FF== 255的掩码- 所需的值.

相信明确的演员是不必要的(它不在我的机器上),但我可能会遗漏一些东西......


编辑:结果演员实际上不必要的.从JLS第5.6.2节:

应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

  • 如果任一操作数是类型double,则另一个操作数转换为double.
  • 否则,如果任一操作数是类型float,则另一个操作数转换为float.
  • 否则,如果任一操作数是类型long,则另一个操作数转换为long.
  • 否则,两个操作数都将转换为类型int.