java八种基本数据类型之byte

来源:互联网 发布:知乎 文案前景 编辑:程序博客网 时间:2024/06/06 13:58

首先,来两个例子:
例子(1)

byte a = 127;a = a + 1;System.out.println(a);

例子(2)

int b = 456;System.out.println((byte)b);

猜一下例子(1)和例子(2)都会输出什么结果?例子(1)会输出128,例子(2)会输出456?那就都错了,其实例子(1)这样写会报错,例子(2)输出的结果是-56
分析一下:java中定义的byte是一个基本数据类型,它的取值被定义为-128~127,byte是一个字节,有八位带符号的二进制数组成的(即8个0或1),那么为什么byte的取值范围是-128~127呢?这就需要我们复习一下计算机的基础理论了。

上面说byte是由带符号位的八个二进制数组成,即第一位为符号位,0代表正数,1代表负数,0000 0001代表1,所以正数最大的是01111 1111为127

负数要注意,在计算机内部,采用2的补码形式保存负数,首先我们来了解一下计算机的原码,反码,补码的计算:

反码:
如果一个数为正数:则它的原码,反码相同
如果一个数为负数:则符号位为1,其余各位按位取反
例如:8和-8
8的二进制表示为0000 1000 反码为0000 1000
-8的二进制表示为1000 1000 反码为1111 0111

补码:
如果一个数为正数:则它的原码,补码相同
如果一个数为负数:补码为负数的绝对值的按位取反然后加1
例如:8和-8
8的二进制表示为0000 1000 补码为0000 1000
-8的绝对值是8,按位取反后为1111 0111 再加1得到1111 1000,所以1111 1000位-8的补码

所以1111 1111代表-1,最小的负数是1000 0000为-128,不妨我们来计算一下1111 1111是补码,我们逆向运算,先减一,得到1111 1110,然后再按位取反,得到0000 0001,得到1,再加上负号即为-1,1000 0000道理一样,最后得到的结果是128,所以能表示最小负数位-128。

好了,回到我们开始的例子,从例子(1)开始,我说这个会报错,是因为a是byte类型的,但是1是int类型的,int类型不能和byte类型直接进行运算。所以会报错,我们可以把例子改为

byte a = 127;a += 1;System.out.println(a);

这样就不会报错了,但是输出的结果是什么呢,我们看一下127的二进制表示是0111 1111,而-128是1000 0000,127+1就是-128,那结果是不是呢?没错,输出结果就是-128

那让我们再看例子(2),b是int类型的,int类型是32位,所以456在计算机中的表示方式是00000000 00000000 00000001 11001000,但是当int强制转换为byte的时候,只保留最后八位,即11001000,这个数最高位是1,所以表示一个负数,而计算机中负数都是以补码形式表示的,我们还得进行转换,即先减一得到1100 0111,然后再按位取反得到0011 1000,结果为56,所以11001000表示的是-56,所以输出结果为-56。

最后,说明一个关于byte类型的说法,不知道大家听没听说过“Java虚拟机中没有byte类型”这个说法,其实也不无道理,我来简单的说明解释一下,java虚拟机对基本类型的操作都是在栈上面完成的,当java处理一个语句的时候,会先把相关的操作数压入到栈中,然后再弹出来进行计算,最后将结果再次压入到栈中,对byte的操作也是一样,但是,在将byte类型压入到栈之前,会将byte类型转换成int类型压入到栈,弹出的也是int类型。结果也是int类型,说以我们进行计算的byte类型都是按照int类型的长度进行计算的,也就是说int将byte类型扩充了,怎么扩充的,下面来解释一下:

比如说正数1,用byte来表示是0000 0001,这个没有问题,但是java虚拟机会对它进行带符号位扩展,0000 0001第一位是0,那么java虚拟机会用0来填充剩下的24位,使其成为一个int类型,结果就是 00000000 00000000 00000000 00000001,int类型也是1

但是,如果想让byte类型的值等于-1,那就不是用int类型的-1表示了,而是找到一个正整数的int类型,然后Java虚拟机对它进行截取,变成byte类型的-1,这个正整数就是2147483647

int a = 2147483647;byte b = (byte)a;

这样b的值就是-1了,因为2147483647二进制表示为01111111 11111111 11111111 11111111,是32位的,但是要强制转换成byte类型的话,Java虚拟机就会将前面的24位全部截掉,剩下1111 1111,而这个数又是补码表示的,我们先减一得到1111 1110,然后按位取反得到0000 0001,得到正数1,所以这个1111 1111表示的是-1,如果我们想要再次转换成int类型,则因为符号位是1,Java虚拟机自动用1填充剩下的24位,结果为11111111 11111111 11111111 11111111,这个数就是int类型的-1

总结:小小byte大世界

0 0