byte存储范围,表示范围
我们知道byte代表1个字节,数据存储的范围:[0x00, 0xFF]。byte变量表示值的范围:[-128, 127]。
下面这段代码并不是输出128,而是输出-128,因为byte变量表示值的范围为[-128, 127]。128刚刚好超出上界127有1单位,溢出为-128。
300对应byte值也不是300,而是按byte长度(1字节)截取存储内容后的值。
可以看到,300 = 0b100101100,截取1byte长度后,值为0b00101100,也就有 b = 0b00101100 => b = 44
byte b = (byte) 128;
System.out.println(b); // 输出-128
byte b = (byte) 300; // 300 = 0b100101100, b = 0b101100
System.out.println(b); // 输出44
byte位运算
还有一种比较有意思的现象,就是byte位运算,中间过程是否进行类型转换,也会影响结果。
请看下面的代码,分别打印出什么?(i1, i2):
byte a = (byte)0xFF;
int i1 = 0xFF & a;
int i2 = a;
System.out.println(i1); // 打印255
System.out.println(i2); // 打印-1
运行程序,发现打印i1 为255,打印i2为-1,同样的byte类型变量a = 0xFF,如果直接转换为int类型,值为-1;如果与0xFF先进行按位与运算,值为255。中间只是对a和0xFF进行了与运算,而a本身宽1字节,但打印结果却不同,这是为什么呢?
猜测是不是跟运算过程中的类型转换有关。下面先做验证:i3的计算,中间参与运算的数全部为byte类型;i4的计算,中间参与运算的数全部为int类型。
结果表明,byte a 先与0xFF进行位运算,跟a和0xFF强制转换为int类型后,再进行&,结果一致;
byte a 直接转换为int类型,跟a和0xFF先强制转换为byte,再进行&,结果一致。
byte a = (byte)0xFF;
int i1 = 0xFF & a;
int i2 = a;
int i3 = (byte)0xFF & (byte)a;
int i4 = (int)0xFF & (int)a;
System.out.println(i1); // 打印255
System.out.println(i2); // 打印-1
System.out.println(i3); // 打印-1
System.out.println(i4); // 打印255