您的位置:首页 > 编程语言 > Java开发

趣事.为啥java中一般用int当做循环的控制变量

2018-03-05 17:05 246 查看

趣事:为啥java中一般用int当做循环的控制变量

引言

相信小伙伴在平时写循环啥的,用Eclipse或者IDEA都能很快速的贴出一段循环体来,而且这些循环的控制条件(以标准for循环为例)都是一个int值,哪怕有的时候我们仅仅循环个几十次,但是我们还是使用了int,而不是一个byte或者short,这是为啥呢。今天就来摸一摸这个底

JVM中的循环

想必大家都知道,咱们的java代码最后都是编译成.class文件加载到jvm后,由jvm再转成各自平台cpu能识别的指令才能执行的,其实今天的这个问题,归根结底就跟jvm的指令集有关。jvm的指令集其实只有一个字节长(1<<8)-1就是最多255个指令,所以在jvm里很多类型的操作指令并没有得到全部的支持,比如缺乏byte,char,short类型的直接操作指令,他们都是共用int类型的操作指令的。

说道这里大家可能想到了,我们在学java的时候就听说在java里整形数据默认为int实现,原来是这么个道理。


说到这可能还有小伙伴不太理解,那么就用一个栗子来说明,

//这个栗子取自java 虚拟机规范 SE8 版
//考虑以下循环
void spin(){
int i;
for(i = 0; i < 100; i++){
;   //Loop body is empty
}
}


这是一个空循环,我们看看编译器会把它变成什么样:

0 iconst_0      //把int类型的0压入操作数栈
1 istore_1      //从操作数栈弹出栈顶元素,并存入临时变量表中下标为1的位置(就是刚那个0)
2 goto 8        //跳转到指令偏移量为8的指令行
5 iinc 1 1      //临时变量表中下标为1的值自增,增量为1
8 iload_1       //把临时变量表下标为1的值压入操作数栈
9 bipush 100    //把int类型的100压入操作数栈
11 if_icmplt 5  //弹出操作数栈顶的2个值,如果第二个值小于第一个就跳转到指令偏移量为5的行(i<100?->5:)
14 return


详细看注释,解释的应该很清楚了

然后咱们来看看用short值当控制变量会怎么样:

void(){
short i;
for(i=0; i < 100; i++){
;   //Loop body is empty
}
}


同样的,我们看看编译之后:

0  iconst_0      //把int类型的0压入操作数栈
1  istore_1      //从操作数栈弹出栈顶元素,并存入临时变量表中下标为1的位置(就是刚那个0)
2  goto 10        //跳转到指令偏移量为10的指令行
5  iload_1        //将临时变量表下标为1的值压入操作数栈
6  iconst_1       //将int类型的1压入操作数栈
7  iadd           //弹出操作数栈顶的两个数,相加,然后将结果压入栈
8  i2s            //弹出栈中第一个元素,将int类型的值转成short类型的,压回去
9  istore_1       //弹出栈中第一个元素,保存到临时变量表的下标1中
10 iload_1       //将临时变量表下标为1的值压入栈
11 bipush 100    //把int类型的100压入操作数栈
13 if_icmplt 5  //弹出操作数栈顶的2个值,如果第二个值小于第一个就跳转到指令偏移量为5的行(i<100?->5:)
16 return


可以清楚的看到,换成short当控制变量后,多了几个指令,这几个指令的作用就是转型,因为最后要返回的i是个short类型的值,而操作的时候没有直接操作short类型的指令,所以这里才这么麻烦要转来转去。所以如果不是为了那点内存空间,大家还是用int吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java jvm