将字节转换为长:为什么有些实现按位与每个字节与 0xff?
Converting bytes to a long: Why do some implementations bitwise-AND each byte with 0xff?
我正在查看 java.io
的 DataInputStream.readLong()
在 SE6 中的实现:
private byte readBuffer[] = new byte[8];
public final long readLong() throws IOException {
readFully(readBuffer, 0, 8);
return (((long)readBuffer[0] << 56) +
((long)(readBuffer[1] & 255) << 48) +
((long)(readBuffer[2] & 255) << 40) +
((long)(readBuffer[3] & 255) << 32) +
((long)(readBuffer[4] & 255) << 24) +
((readBuffer[5] & 255) << 16) +
((readBuffer[6] & 255) << 8) +
((readBuffer[7] & 255) << 0));
鉴于 readBuffer[] 是一个 字节的数组,为什么需要 &
每个字节 255?
当单个字节被转换为 long
时,long 的剩余位 (9-64) 位是否应该自动设置为零,从而使 &
变得不必要?
防止负值字节的符号扩展。
java 的字节类型是有符号的,所以 0xff (255) == -1,在从字节扩展到 int/long 期间 - 有符号的值被保留,所以如果你只有代码:
final byte a = (byte)0xff;
final long b = a;
System.out.println(b); // output here is -1, not 255
所以,这里来一个技巧:
final byte a = (byte)0xff;
final long b = a & 0xff; // binary and between byte A and int 0xff
System.out.println(b); // output here is 255
因此,由于符号扩展,第一个字节变量 a 被提升为 int(并变为 0xffffffff),然后我们通过按位 AND
截断它
我正在查看 java.io
的 DataInputStream.readLong()
在 SE6 中的实现:
private byte readBuffer[] = new byte[8];
public final long readLong() throws IOException {
readFully(readBuffer, 0, 8);
return (((long)readBuffer[0] << 56) +
((long)(readBuffer[1] & 255) << 48) +
((long)(readBuffer[2] & 255) << 40) +
((long)(readBuffer[3] & 255) << 32) +
((long)(readBuffer[4] & 255) << 24) +
((readBuffer[5] & 255) << 16) +
((readBuffer[6] & 255) << 8) +
((readBuffer[7] & 255) << 0));
鉴于 readBuffer[] 是一个 字节的数组,为什么需要 &
每个字节 255?
当单个字节被转换为 long
时,long 的剩余位 (9-64) 位是否应该自动设置为零,从而使 &
变得不必要?
防止负值字节的符号扩展。
java 的字节类型是有符号的,所以 0xff (255) == -1,在从字节扩展到 int/long 期间 - 有符号的值被保留,所以如果你只有代码:
final byte a = (byte)0xff;
final long b = a;
System.out.println(b); // output here is -1, not 255
所以,这里来一个技巧:
final byte a = (byte)0xff;
final long b = a & 0xff; // binary and between byte A and int 0xff
System.out.println(b); // output here is 255
因此,由于符号扩展,第一个字节变量 a 被提升为 int(并变为 0xffffffff),然后我们通过按位 AND
截断它