字节码指令了解数组和遍历

1.数组

数组是JVM内置的一种对象类型,这个对象同样是继承的Object类。我们使用代码来理解一下

/**
 * @author 公众号:三明治聊IT
 * @date 2021/6/13
 */
public class ArrayDemo {
    int getValue() {
        int[] arr = new int[]{1111,2222,3333,4444};
        return arr[2];
    }

    int getLength(int[] arr) {
        return arr.length;
    }
}

getValue字节码

1.1 数组创建

可以看到,新建数组的代码,被编译成了newarray指令

newarray 10 (int)

数组里的初始化内容,被顺序编译成了一系列指令放入:

  • sipush 将一个短整型常量值推送至栈顶;
  • iastore 将栈顶int型数值存入指定数组的指定索引位置。

    具体操作:
    1.dup, 索引数组下标
    2.iconst_0, 常量0,入操作数栈
    3.sipush, 将一个常量1111加载到操作数栈
    4.将栈顶int型数值存入数组0索引位置
    为了支持多种类型,从操作数栈存储到数组,有更多的指令:bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore。

1.2 数组访问


数组元素的访问,是通过第28~30行代码来实现的

  • aload_1 将第二个引用类型本地变量推送至栈顶,这里是生成的数组
  • iconst_2 将int型2推送至栈顶
  • iaload 将int型数组指定索引的值推送至栈顶

获取数组的长度,是由字节码指令arraylength来完成的

2 遍历

无论是Java的数组,还是List,都可以使用foreach语句进行遍历,虽然在语言层面它们的表现形式是一致的,但实际实现的方法并不同。

import java.util.List;

/**
 * @author 公众号:三明治聊IT
 * @date 2021/6/14
 */
public class ForLoopDemo {
    void loop(int[] arr) {
        for (int i : arr) {
            System.out.println(i);
        }
    }

    void loop(List<Integer> list) {
        for (int i : list) {
            System.out.println(i);
        }
    }
}

数组:它将代码解释成了传统的变量方式,即for(int i;i<length;i++) 的形式。
List: 它实际是把list对象进行迭代并遍历的,在循环中,使用了Iterator.next()方法。
使用jd-gui反编译工具,可以看到实际生成的代码:

再看这两个的字节码
loop数组的字节码:

 0 aload_1
 1 astore_2
 2 aload_2
 3 arraylength
 4 istore_3
 5 iconst_0
 6 istore 4
 8 iload 4
10 iload_3
11 if_icmpge 34 (+23)
14 aload_2
15 iload 4
17 iaload
18 istore 5
20 getstatic #2 <java/lang/System.out>
23 iload 5
25 invokevirtual #3 <java/io/PrintStream.println>
28 iinc 4 by 1
31 goto 8 (-23)
34 return

loop list的字节码:

 0 aload_1
 1 invokeinterface #4 <java/util/List.iterator> count 1
 6 astore_2
 7 aload_2
 8 invokeinterface #5 <java/util/Iterator.hasNext> count 1
13 ifeq 39 (+26)
16 aload_2
17 invokeinterface #6 <java/util/Iterator.next> count 1
22 checkcast #7 <java/lang/Integer>
25 invokevirtual #8 <java/lang/Integer.intValue>
28 istore_3
29 getstatic #2 <java/lang/System.out>
32 iload_3
33 invokevirtual #3 <java/io/PrintStream.println>
36 goto 7 (-29)
39 return
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT三明治

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值