4

gotoステートメントを、、、、、およびステートメントなどifに機械的に変換する方法、または関数呼び出し、オブジェクトなどを使用して変換する方法はありswitchますwhileか?breakcontinue

4

7 に答える 7

10

良いアイデアではありませんが、ループとswith-caseを使用することは可能です。次の例では、goto変数は、続行するときに移動するラベル(0、1、2、またはデフォルト)を決定します。

int goTo=0;
while(true){
  switch(goTo){
  case 0:
    doSomething();
    goTo = 1;
    continue;
  case 1:
    doSomethingElse();
    goTo = 2;
    continue;
  case 2:
    doSOmethingDifferent();
    goTo = 0;
    continue;
  default:
    return;
  }
}
于 2009-09-28T13:56:25.537 に答える
6

これはここで共有する価値があると思いました。ある日、Redditでこれを見ました。これは、カスタムクラスローダーを介した任意の行番号(同じ.javaファイル内)へのgotoの実装です。これは楽しいコードです。http://steike.com/tmp/goto.zip。私はそれを信用しません。

編集:好奇心が強いが、zipをダウンロードして実行したくない場合は、次のファイルを参照してください。

public class GotoDemo {

    public static void main(String[] args) {
        int i = 5;
        System.out.println(i);
        i = i - 1;
        if (i >= 0) {
            GotoFactory.getSharedInstance().getGoto().go(4);
        }

        try {
            System.out.print("Hell");
            if (Math.random() < 2) throw new Exception();            
            System.out.println("World!");
        } catch (Exception e) {
            System.out.print("o ");
            GotoFactory.getSharedInstance().getGoto().go(13);            
        }
    }
}

印刷されます:

   3
   2
   1
   0
   Hello World!
于 2009-09-28T14:00:07.607 に答える
4

gotoジャンプする場所に基づいて作成できる複雑さを考えると、それは非常に疑わしいものです。

于 2009-09-28T13:47:01.717 に答える
4

Java 言語は、任意の位置への goto をシミュレートするために必要な機能をサポートしていません (同じメソッド内であっても)。gotoあなたが言及した構造を使用していくつかの簡単な使用法を実装できgotoますが、この方法ですべての可能な使用法を実装することはできません。(*)

バイト コード レベルではおそらくgoto(少なくともメソッド内で) 実装できますが、この場合、そのバイト コードを有効な Java コードにマップし直すことはできませんでした。

メソッドまたはオブジェクトの境界をgoto越える s については、JVM レベルでは絶対に禁止事項です。Java セキュリティ モデル全体は、コードが検証可能であり、エントリ ポイント (「メソッド」とも呼ばれます) のみが定義されているという事実に依存しています。

(*) 免責事項: これは、goto の効果を実装するためにメソッドを完全に再構築したくないことを前提としています。これは、コードの重複を引き起こし、メソッドの「通常の」フローを難読化する可能性もあります。Javaメソッドでチューリングマシンを実装できるので、Javaメソッドで「goto」を確実に実装できます;-)

于 2009-09-28T13:49:11.977 に答える
2

確かに:(わかりやすくするために少し省略しています)

int goTo = 0; boolean done = false;
while (!done) {
  switch (goTo) {
     default:
     case 1: System.out.println("We're at line 1!"); goTo = 2; break;
     case 2: System.out.println("We're going to line 4!"); goTo = 4; break;
     case 3: System.out.println("We're at line 3 and we're done!"); done = true; break;
     case 4: System.out.println("We're at 4, going to 2! Screw you, line 3!"); goTo = 2; break;
  }
}

なぜそんなことをしたいのかは私にはわかりませんが、ねえ、できます...

于 2009-09-28T14:37:34.160 に答える
0

はい、あなたが言及した方法の組み合わせを使用して...可能です(実際には何でも可能です。それを適切に行う方法を理解するだけでもお尻の痛みです)。

は非常に複雑な実行パスになる可能性があることに注意してくださいgoto...したがって、生成されたものに見苦しい大量の重複コードが発生する可能性があります。

于 2009-09-28T13:52:12.030 に答える
0

実際にはgoto、特にメソッド抽出が許可された変換である場合、特定の例を別のものに変換できると思います。これは抽象的な質問ですか、それとも、実際のツールが本当に必要なほど多くの goto がありますか? おそらく、Javaコード自体が何かから機械翻訳されたのでしょうか?

goto私は純粋主義者を困らせるためだけに、私が書いたすべてのプログラムに1 つの actual を入れていました。

于 2009-09-28T13:54:13.607 に答える