这是来自于一个Bug的经验教训。服务端序列化一个大小为2个字节的无符号整形数,客户端收到后按位或来自恢复(每个字节存为byte)。原始代码:
int v = (data[offset++] << 8) | (data[offset++]);
无符号整形数0x00D6在接收到解出来变成了-42。
原因其实很简单,是因为byte本身是有符号的,它放不下0xD6。改动也比较简单:
int v = ((status[offset++] << 8) & 0xFF) | ((status[offset++]) & 0xFF);
附测试的小程序
public class ByteSheft {
public static void main(String[] args){
byte[] status = new byte[2];
status[0] = 0x00;
status[1] = (byte) 0xD6;
int v1 = ((status[0] << 8) | (status[1]));
int v2 = (status[0] << 8);
int v3 = (status[1]);
int v4 = (status[1] & 0xFF);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
}
}
在赋值的第五行,如果没有强转编译器会报错,其实这个错误信息也我们提示了这个错误。
输出:
-42
0
-42
214