用Java字节码转到


问题内容

因此,有一天,当我在Wikipedia页面上查看Java字节码时,遇到了以下示例:

考虑以下Java代码:

  outer:
  for (int i = 2; i < 1000; i++) {
      for (int j = 2; j < i; j++) {
          if (i % j == 0)
          continue outer;
     }
     System.out.println (i);
  }

假设将上述代码放在方法中,Java编译器可能会将上述Java代码转换为字节代码,如下所示:

  0:   iconst_2
  1:   istore_1
  2:   iload_1
  3:   sipush  1000
  6:   if_icmpge       44
  9:   iconst_2
  10:  istore_2
  11:  iload_2
  12:  iload_1
  13:  if_icmpge       31
  16:  iload_1
  17:  iload_2
  18:  irem
  19:  ifne    25
  22:  goto    38
  25:  iinc    2, 1
  28:  goto    11
  31:  getstatic       #84; //Field java/lang/System.out:Ljava/io/PrintStream;
  34:  iload_1
  35:  invokevirtual   #85; //Method java/io/PrintStream.println:(I)V
  38:  iinc    1, 1
  41:  goto    2
  44:  return

而且我注意到,很少有goto出现过几次,这在检查JVM规范时是有效的。
我的问题是为什么?
GOTO在Java中是一个保留的但无法使用的关键字,因此为什么在编写和编译Java代码时似乎会使用goto将其编译回去。我想知道这仅仅是在较低级别的编程中总是会做的事情,还是因为JVM被信任可以更有效地使用goto字。最终,我对为什么goto被认为是一种不好的做法感到好奇,以至于Java代码中禁止使用goto,但是似乎在编译时直接将其放回了您的代码中。


问题答案:

诸如循环(for/ while)之类的Java结构化编程功能是在字节码级别使用条件分支(IF..)和无条件跳转(GOTO)指令实现的。

break``continue在结构化编程中,也可以认为Java语言具有这些功能(中断/继续标记),对于外部循环或外部循环也被认为足够有用且合法。

在JVM /字节码级别,这些也可以通过实现GOTO

看到: