正文
一个简单的 for each
操作
我们写一个简单的 Main.java
来对数组进行 for each
操作(Main.java
的内容如下)
public class Main {
public int f(int[] nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
return sum;
}
}
执行如下命令可以看到字节码中的内容
javac Main.java
javap -cp . -p -v 'Main'
完整的内容较长,和 f(...)
直接相关的部分如下
public int f(int[]);
descriptor: ([I)I
flags: ACC_PUBLIC
Code:
stack=2, locals=7, args_size=2
0: iconst_0
1: istore_2
2: aload_1
3: astore_3
4: aload_3
5: arraylength
6: istore 4
8: iconst_0
9: istore 5
11: iload 5
13: iload 4
15: if_icmpge 35
18: aload_3
19: iload 5
21: iaload
22: istore 6
24: iload_2
25: iload 6
27: iadd
28: istore_2
29: iinc 5, 1
32: goto 11
35: iload_2
36: ireturn
LineNumberTable:
line 3: 0
line 4: 2
line 5: 24
line 4: 29
line 7: 35
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 11
locals = [ class Main, class "[I", int, class "[I", int, int ]
stack = []
frame_type = 248 /* chop */
offset_delta = 23
内容有点多,还是借助 cfr 来分析吧。
以 cfr-0.144.jar
为例,执行如下命令,就能看到编译器操作之后的 for each
是什么样子了。
java -jar cfr-0.144.jar Main --arrayiter false
执行结果如下
/*
* Decompiled with CFR 0.144.
*/
public class Main {
public int f(int[] arrn) {
int n = 0;
int[] arrn2 = arrn;
int n2 = arrn2.length;
for (int i = 0; i < n2; ++i) {
int n3 = arrn2[i];
n += n3;
}
return n;
}
}
由此可见,编译器会自动将针对数组的 for each
操作转化为普通的 for
循环。
网友评论