2009-09-28 64 views
4

有没有办法来翻译机械陈述gotoifswitchwhilebreakcontinue报表等,或函数调用,对象,什么?翻译goto语句来如果交换机,同时,破发等

+1

到底为什么你需要知道这一点?这只是一个思想实验,或者你有什么真正的理由? – Kip 2009-09-28 13:59:24

+1

模拟一个goto应该是不必要的 - 在极少数情况下,使用goto不是一个糟糕设计的症状。 – 2009-09-28 14:02:31

回答

9

虽然这不是一个好主意,但可以使用循环和开关。在下面的例子中,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; 
    } 
} 
+2

实际上没有什么内在的关于该代码块的坏主意(虽然我不知道是否将它用作解决没有goto的方法)这只是一个有限状态机的基本实现,它有很多合法目的。 – Falaina 2009-09-28 14:06:13

+0

Java中的while循环不能具有整数条件。 'while(true)' – pjp 2009-09-28 14:07:01

+1

谢谢pjp。能够将1作为true和0传递为false是我真正希望他们添加到Java中的一件事。其余的是美好的。 – Marius 2009-09-28 14:19:07

3

考虑到这goto的可以创建基于其地方之间的跳跃,这是非常值得怀疑的复杂性。

+0

我把原来的问题表示为:“我有一个应用程序使用goto遍布整个地方,我想创建一个应用程序来完成代码,并用if来替换goto,for循环,函数等等摆脱他们。“当我试图回答这个问题时,其他人似乎试图回答“我怎样才能做出一个模拟使用goto的开关?”我认为这些用处不大。 – 2009-09-28 15:05:02

+0

+1我明白你的意思 – Kip 2009-09-28 15:15:03

+0

+1你以同样的方式阅读问题,我或多或少同意你的答案。可能会自动检测和替换GOTO的特定用途 - 但在一般情况下这样做可能不可行。 – slim 2009-09-28 15:29:39

4

Java语言不支持将goto模拟到任意位置所需的功能(即使在相同的方法中也不行)。您可以使用您提到的构造实现goto的一些简单用途,但不能实现所有可能的goto这种方式。 (*)

在字节代码级别上,您可能实现goto(至少在方法中),但是在这种情况下,该字节代码无法映射回有效的Java代码。

至于goto s表示交叉法或对象边界:这绝对是一个很大的禁忌在JVM上水平。整个Java安全模型取决于代码可验证的事实,因此只有定义的入口点(也称为“方法”)。 (*)免责声明:这里假定您不想完全重构方法来实现goto的效果,也可能会调用代码重复和混淆方法的“正常”流。既然你可以在Java方法实现图灵机你绝对可以实现“转到”在Java方法;-)

0

是,使用你所提到的方法的组合......这是可能的(一切皆有可能真的,只是想清楚如何正确地做到这一点是屁股疼痛)。

请记住,goto可能会导致极其复杂的执行路径...因此可能会导致在生成的任何内容中出现难看的大量重复代码。

+0

它不需要*重复,必要时只需要大量的样板。见下文。 – 2009-09-28 14:38:52

0

在实践中,我想任何给定的例子goto可以被翻译成别的东西,特别是如果方法提取是允许的转型。这是一个抽象的问题,还是你真的有这么多的goto,你真的需要一个实际的工具?也许java代码本身是从某种机器翻译过来的?

我习惯把一个实际goto到每一个项目我写只是为了激怒较真。

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! 
+7

这很有趣......一个可怕的方式。 – 2009-09-28 14:14:13

+1

我的大脑在哭泣 – Kip 2009-09-28 15:15:46

+0

@JoachimSauer最可怕的部分是单身。 – rightfold 2014-11-25 08:22:46

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; 
    } 
} 

为什么你会想要做这样的事我是无法理解,但是,嘿,你可以 ...

+1

这与Marius的回答几乎完全一致。正如那里指出的那样,这是一个有限状态机(即将“goTo”更改为“状态”)。FSM没什么问题,但将它用作goto解决方法会很奇怪。 – Kip 2009-09-28 14:47:33

+0

是的,他在我编辑窗口时发布了......多线程的危险...... 这很奇怪。但它回答了OP的要求。 – 2009-09-28 17:16:08