21

先日、ウィキペディアの 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 コードで禁止されているほど悪い慣行と見なされているのに、コンパイル時にコードに直接戻されるように見える理由について興味があります。

4

9 に答える 9

8

goto言語キーワードとバイト コードまたはアセンブリ命令を区別する必要がありますgoto

gotoC のような高レベル コードでジャンプを使用するのは悪い習慣です。したがって、Java では許可されていません。

後藤に関する元の Edsger W. Dijkstra 論文

コンパイルされたコードでは、無条件ジャンプ命令 gotoの使用は完全に問題ありません。コンパイラによってそこに配置され、データの初期化、メモリの割り当て解除など、コードをジャンプすることの意味を忘れません。

于 2013-11-15T09:02:24.513 に答える
4

バイトコードは、仮想マシン用のある種のアセンブリ言語です。機械語でジャンプ命令を持つことは非常に一般的です。goto は無条件ジャンプ命令です。

Java コンパイラは、メソッド本体内のほぼすべての制御フロー ステートメントを goto 命令に変換します。

goto キーワードはおそらく Java で予約されており、その存在が重要であることが判明した場合に備えて、新しいバージョンに追加するオプションを保持しています。マシンの観点からは、実際には goto に問題はありません。人間にとって非常に読みにくいコードを記述できるため、評判が悪い. Java 言語では、goto の代わりに、ラベルを使用してブレーク アンド コンティニュを使用できます。

于 2013-11-15T09:02:06.127 に答える
2

gotoマシンレベルでは問題ありません.Javaコンパイラはコードを記述していません.コードをJavaソースからバイトコードに変換するだけです.

コードを書いている人にとっては、これは別の話です。goto 命令は読みにくく、分析しにくく、多くの goto ジャンプの後でコードは混乱します。これが、ジャンプ命令の代わりに OO の概念を使用する必要がある理由です。

于 2013-11-15T09:05:14.943 に答える
1

JVM のマシン コードに相当するものを見ています。Java で許可されているかどうかgotoは、JVM バイトコードでポインターが許可されていないのと同様に、バイトコードで許可されているかどうかとは無関係ですが、JVM は確実にバイトコードをポインターを使用するマシン コードにコンパイルまたは解釈します。

于 2013-11-15T09:00:17.683 に答える
0

バイトコードは Java ではありません。Groovy などの他の言語のプログラムはバイトコードにコンパイルできます。BCEL などのツールを使用してバイトコードを直接記述できます。gotoは低レベルでないと行けません。

于 2013-11-15T09:03:50.223 に答える
0
  1. SpaceTrucker は (head の質問へのコメントで) Java 言語自体とバイトコードの違いについて言及しました。gotoキーワードとgoto命令は同じではありません。唯一の共通点は名前です。バイトコードの場合はJUMP( JMP) の命令だけです。
  2. 基本的にgoto、「スパゲッティ」コードを実現し、コードの可読性を悪化させるため、プログラミング/コーディングの悪い習慣であると考えられています。
于 2013-11-15T09:05:22.810 に答える