分析java的for循环和数组初始化的执行过程

上周论坛有个帖子讨论有关for的写法,说是有个代码评审批评了下属的代码写法问题,具体见链接:

http://www.iteye.com/topic/722599

 

大家的一致意见是楼主写法没有问题,"问题是数组长度的的写法,应该先用变量保存,循环里不要直接计算",这里我感到怀疑。

 

我也回复了该贴,说是看下for的"源码",这里的意思是for的执行过程,有同学问我怎么看,这里做下分析,

过程很简单,就是用javap 命令来反编译.class文件即可,下面我们从数组构建开始,一个一个的分析.

 

1:javap -c 命令分析数组的构建

 

public class E{
         
         public static void main(String...args){
                int[] arr={1,2,3};
                int[] arr2={1,2,3};
         }

}

 

 

分析结果如下:

0:iconst_3                     //常数3装载到操作数栈:需要初始化数组的长度

1:newarray int              //堆中new一个新的int类型的数组

3:dup                            //直接操纵操作数栈,打开操作

4:iconst_0                    //常数0装载到操作数栈:数组下标

5:iconst_1                    //常数1装载到操作数栈:对应的值

6:iastore                      //把一个值从操作数栈存入到数组成分:arr[0]=1

7:dup                           //...

8:iconst_1                   //...

9:iconst_2                   //...

10:iastore                   //...arr[1]=2

11:dup                        //...

12:iconst_2                 //...

13:iconst_3                 //...

14:iastore                   //...arr[2]=3

15:astore_1                //...为局部变量存入第一个值,该值为以上在操作数栈构造完成的数组类型16:iconst_3                 //---------开始构造第二个数组

17:newarray int          //

19:dup                        //

20:iconst_0                 //

21:iconst_1                 //

22:iastore                   //

23:dup                        //

24:iconst_1                 //

25:iconst_2                 //

26:iastore                   //

27:dup                        //

28:iconst_2                //

29:iconst_3                //

30:iastore                  //

31:astore_2               //----------存入第二个数组完成

33:return                   //结束返回

 

2:javap -c 命令分析循环的构建

 

public class D{
      public static void main(String...args){
            for(int j=0;j<2;){
           }
      }
}

 

分析结果如下:

0:iconst_0                  //常数0装载到操作数栈

1:istore_1                  //存入第一个值到局部变量:j=0的赋值操作

2:iload_1                   //调出第一个局部变量到操作数栈:取出j的值

3:iconst_2                 //常数2装载到操作数栈

4:if_icmpge    10        //判断大小:j<2,若不成立直接跳转到10行

7:goto 2                    //跳转到2行继续执行

10:return                  //结束返回

 

 

3:有了以上基础知识,我们来分析http://www.iteye.com/topic/722599中的两种模式的循环结构

 

3.1:javap -c 分析String类型的数组循环的构建

...吃饭去,回来接着写

继续:变量声明在外部的情况

 

public class D{
      public static void main(String...args){
            String[] arr={"1","2","3"};
            String i=null;
            for(int j=0;j<arr.length;j++){
                   i=arr[j];
            }
      }
}

 

分析结果如下:

0:iconst_3

1:anewarray #2;//class java/lang/String

4:dup

5:iconst_0

6:ldc #3;//String   1       //将字符串1的引用push到操作数栈

8:aastore                       //将一个值(数组类型)从栈存入到数组成分

9:dup

10:iconst_1

11:ldc   #4;//String 2

13:aastore

14:dup

15:iconst_2

16:ldc   #5;//String 3

18:aastore

19:astore_1                   //存入第一个值到局变(数组类型)chushihua

20:aconst_null               //申明数组类型常量为null

21:astore_2                   //存入第二个值到局变(数组类型)初始化i完成

22:iconst_0                    //装载常数0到操作数栈(整形)

23:istore_3                    //从栈存入第三个值到局变(整形)

24:iload_3                     //将第三个局变调入栈(整形)

25:aload_1                    //将第一个局变调入栈(数组类型) 

26:arraylength              //计算数组长度

27:if_icmpge  40            //比较大小

30:aload_1                    //将第一个局变调入栈(数组类型)

31:iload_3                     //将第三个局变调入栈(整形)

32:aaload                      //将一个数组成分装载到操作数栈(该数组的成员类型为数组类型)

33:astore_2                  //从栈把第二个值存入到局变(数组型),覆盖之前第21行的存入局变的值 

34:iinc  3,1                    //第三个局变自增1(整型)

37:goto 24                    //转向第24步

40:return                       //结束返回

 

 

3.2变量声明在内部的情况

 

public class D{
      public static void main(String...args){
            String[] arr={"1","2","3"};
            for(int j=0;j<arr.length;j++){
                 String i=arr[j];
            }
     }
}

 

分析结果如下:

0:iconst_3

1:anewarray #2;//class java/lang/String

4:dup

5:iconst_0

6:ldc #3;//String 1

8:aastore

9:dup

10;iconst_1

11:ldc #4;//String 2

13:aastore

14:dup

15:iconst_2

16:ldc #5;//String 3

18:aastore

19:astore_1                   //初始化arr完成

20:iconst_0

21:istore_2

22:iload_2

23:aload_1

24:arraylength

25:if_icmpge 38

28:aload_1

29:iload_2

30:aaload

31:astore_3                   //从栈存入第三个值到局变(数组类型),在下次循环的时候会被覆盖

32:iinc 2,1

35:goto 22

38:return

 

从上面两个例子可以得出两种写法的差别,至于那个评审所说的浪费空间?????????

 

结束.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值