4

有没有办法将goto语句机械地翻译成ifswitchwhilebreakcontinue语句等,或者使用函数调用、对象等?

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 文件中)的实现。这是一段有趣的代码。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值,只是为了惹恼纯粹主义者。

于 2009-09-28T13:54:13.607 回答