考虑这两种方法:
public static void forLoop(int start, int limit) {
for (int i = start; i < limit; i++) {
}
}
public static void whileLoop(int start, int limit) {
int i = start;
while (i < limit) {
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
编译时,它们会产生字节码(这是详细的输出javap):
public static void forLoop(int, int);
descriptor: (II)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=2
0: iload_0
1: istore_2
2: iload_2
3: iload_1
4: if_icmpge 13
7: iinc 2, 1
10: goto 2
13: return
LineNumberTable:
line 6: 0
line 9: 13
LocalVariableTable:
Start Length Slot Name Signature
2 11 2 i I
0 14 0 start I
0 14 1 limit I
public static void whileLoop(int, int);
descriptor: (II)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=2
0: iload_0
1: istore_2
2: iload_2
3: iload_1
4: if_icmpge 13
7: iinc 2, 1
10: goto 2
13: return
LineNumberTable:
line 12: 0
line 13: 2
line 14: 7
line 16: 13
LocalVariableTable:
Start Length Slot Name Signature
0 14 0 start I
0 14 1 limit I
2 12 2 i I
Run Code Online (Sandbox Code Playgroud)
如您所见,这两种方法的代码部分完全相同.但是,当我使用JD反编译此类时,它正确生成:
public static void forLoop(int start, int limit) {
for (int i = start; i < limit; i++) {}
}
public static void whileLoop(int start, int limit)
{
int i = start;
while (i < limit) {
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
怎么能这样做?这些方法的字节码完全相同!尽管每个方法的属性LineNumberTable和LocalVariableTable属性都不同,但我不愿意相信这是因为那些不是Code包含方法属性的必需属性(根据Java语言规范的第4.7节,Java SE 8版)).
行号和局部变量范围.
for 环:
LineNumberTable:
line 6: 0
line 9: 13
LocalVariableTable:
Start Length Slot Name Signature
2 11 2 i I
0 14 0 start I
0 14 1 limit I
Run Code Online (Sandbox Code Playgroud)
while 环:
LineNumberTable:
line 12: 0
line 13: 2
line 14: 7
line 16: 13
LocalVariableTable:
Start Length Slot Name Signature
0 14 0 start I
0 14 1 limit I
2 12 2 i I
Run Code Online (Sandbox Code Playgroud)
该for回路具有更少的代码线条分明的-这是有道理的,因为它包装了一个线上的初始化和增量.