gpt4 book ai didi

java - Java 中 `for` 循环指令的意外排序

转载 作者:行者123 更新时间:2023-11-29 08:35:23 24 4
gpt4 key购买 nike

考虑以下极其简单的循环,它的间隔有点有趣:

    /* 01 */  System.out.println(10);
/* 02 */ for(
/* 03 */ int i = 0;
/* 04 */ i < 100;
/* 05 */ i++)
/* 06 */ System.out.println(i);

第 1 行并不重要。它只是在循环本身之前为 Eclipse 调试器创建一个起点。

当我在调试器中运行我的代码时,我希望看到以下行的运行时顺序:

1, 3, 4,然后是一系列重复的 6, 5, 4, (6, 5, 4, 6, 5, 4, 6, 5, 4...)

相反,我得到的是

1, 3, 4,然后是重复的系列 2, 6, 5, 4, (2, 6, 5, 4, 2, 6, 5, 4...)

显然这没有什么实际意义——循环完全按预期运行。但我计划为我的类(class)创建一个新概念的演示,这个额外的执行步骤使得我正在展示的(有点困难的)代码更难在调试器中遵循。

我希望能够通过向他们解释发生了什么来消除一些困惑。为什么第 2 行被重新表示为一个步骤?那一刻发生了什么?

最佳答案

发生这种情况是因为 Java 字节码有一条用于比较+跳转的融合指令,一条指令是可以具有行号或可以单步执行的最小量程。

您正在使用的 Eclipse ECJ 似乎强调了跳转,并将比较+跳转注释为 for 循环本身的一部分。这会导致在每次比较/跳转期间在 02 上停止。

OpenJDK 似乎强调“比较”方面,并将其注释为 for 循环条件的一部分。这给出了您期望的结果,在 02 上没有停止。

两者都没有直接错误,但我也倾向于赞成您的解释。也许您可以说服 Eclipse 使用 OpenJDK 进行这个特定的演示,或者使用不同的 Java 调试器?

下面是反汇编的字节码+调试信息。欧洲法院将条件放在底部:

  public static void main(java.lang.String[]);
Code:
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: bipush 10
5: invokevirtual #22 // Method java/io/PrintStream.println:(I)V
8: iconst_0
9: istore_1
10: goto 23
13: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
16: iload_1
17: invokevirtual #22 // Method java/io/PrintStream.println:(I)V
20: iinc 1, 1
23: iload_1
24: bipush 100
26: if_icmplt 13 // HERE
29: return
LineNumberTable:
line 3: 0
line 5: 8
line 6: 10
line 8: 13
line 7: 20
line 6: 23
line 4: 26 /* 02 */ in your code
line 9: 29

OpenJDK 提供了更直接的翻译,需要倒置条件,其中没有使用 for( 行注释的指令:

  public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: bipush 10
5: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
8: iconst_0
9: istore_1
10: iload_1
11: bipush 100
13: if_icmpge 29
16: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
19: iload_1
20: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
23: iinc 1, 1
26: goto 10
29: return
LineNumberTable:
line 3: 0
line 5: 8
line 6: 10
line 8: 16
line 7: 23
line 9: 29

关于java - Java 中 `for` 循环指令的意外排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44475962/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com