解密Java byte类型的一个小问题

来源:互联网 发布:cn是哪个国家的域名 编辑:程序博客网 时间:2024/05/28 09:33

大家先看一下下面的代码

public class Main {    public static void main(String[] args) {        byte a = 1;        byte c = 2;        byte b =  a + c;//编译报错    }}

其中byte b = a + c;这句代码会报一个类型不匹配的错误,说不能将int类型转换成byte类型。WTF?!,两个byte类型的变量相加再赋值给一个byte类型变量,这是哪门子的类型不匹配呀,那个int又是哪来的!然后改成byte b = (byte) (a + c);又能行了。这几句代码,其实包含了很多的Java的秘密,容我慢慢说来。

首先你应该知道的是,byte a = 1;byte c = 2;这两句右边的数值1和2是一种叫字面值常量的东西,像"abc"是字符串类型的字面值常量,Java编译器会把数值的字面值常量默认为int类型的

大家应该都清楚,将一个int型变量赋值给一个byte型变量就会产生我一开始说的类型不匹配错误,如下面的代码

int a = 1;byte b = a;

像1和2虽然是int型数据,但是它们并不是一个int型变量记录的值,它们在编译的时候就是已知的了,所以只要不超出byte范围直接赋值给byte变量还是能行的,要是超出了byte范围如128那就会报一个类型不匹配错误。

那么回到问题所在,为什么两个byte类型变量相加再赋值给byte类型变量会报错呢?根据错误信息可以得知a + b后所得到的结果应该是一个int类型数据。所以我们真正要弄清楚的是为什么两个byte变量相加会得出一个int类型数据。

这个时候就要谈到Java虚拟机搞的一个小动作了。虚拟机遇到涉及byte、short和char类型的运算操作首先会把这些值转换为成int类型,然后对int类型值进行运算,最后得到int类型的结果,就连boolean类型也会变成int类型的0或1。所以这就是为什么两个byte变量相加会得出一个int类型数据,所以short和char也会出现类似的问题。

至于虚拟机为什么要这么做,我在网上找到了一个感觉比较靠谱的答案

因为32位的系统(x86系列的寄存器啥的)一次能够处理4个字节,也就是32位,所以直接搞32位的数据就不必进行什么数据的对齐 啊补全啊什么的。。换句话,为了速度喽。

另外对于64位CPU和64位开发运行环境,使用long更好,因为long才是64位的。

0 0
原创粉丝点击