1.
InputStream.read()方法.
read()方法说明是返回读取到的一个字节,但是为什么返回类型是int而不是byte呢?
原因在于byte类型是8位,也就是8个0或1组成的一串。java里第一位是0表示正数,第一位是1表示负数。
而ascii码的范围是0~255,但是一个byte的八位 最多表示~128 - 127 的范围(第一位符号位,所以只有剩下的7位表示大小)。
这时候假如read()读取到一个字节是10101010 ,这时候不考虑符号位,直接计算大小 就是170 考虑符号位就是 -86(反码需要全部位取反再加1).
而ascii码是没有负数的,所以应该返回的是 170,而不是 -86 .
这时候通过 byte & 0x ff 就能得到170 . (0xff 是int类型,其实是0x000000ff ,也是00000000000000000000000011111111).
运算完之后的结果就是 在原来byte的八位 前面加了 24个0,变成了int类型(这时候第一位是0,变成正数了)
2.
我们用Integer.toHexString(int value) 这个方法时,需要传递一个int类型,假如我们要输出一个byte类型的十六进制字符串表示该怎么办呢?
假如byte 是 10101010 ,那么应该输出0xAA 。 假如我们直接把这个byte传给Integer.toHexString(int value) ,那么byte会被转成int ,这时候转换规则是 符号位 是什么,前面24位就添加什么。 这时候符号位是1, 转成int后就是 11111111 11111111 11111111 10101010 ,它的十六进制字符串表示为 0xffffffAA, 很显然 0xffffffAA 和 0xAA是不一样的(0xAA 是 0x000000AA) ,所以我们通过 byte & 0xff ( 0xff就是0x000000ff) ,这样前面24位就清零了 于是 10101010 & 0xff 运算结果等于 0x000000AA,这时候传给Integer.toHexString 就能显示0xAA了,
*需要注意的是 这仅仅是正确的十六进制字符串表示,
原来的byte数是10101010,是个负数,按java反码的规则,它表示十进制的-86
直接转换成int ,也就是 (int)10101010 后变成 11111111 11111111 11111111 10101010,这时候按反码规则计算后也是 -86
但是&0xFF后, 变成了00000000 00000000 00000000 10101010,这时候变成正数了,表示170.(并不是之前byte表示的-86,但是这时候的16进制字符串才正确)