280

我对此感到困惑。我们大多数人都被告知在 Java 中没有任何 goto 语句。

但是我发现它是Java中的关键字之一。它可以在哪里使用?如果不能使用,那为什么在 Java 中将它作为关键字包含在内?

4

23 回答 23

240

James Gosling 创建了支持goto语句的原始 JVM,但后来他删除了这个不必要的特性。主要原因goto是不必要的,因为通常可以用更易读的语句(如break/continue)或通过将一段代码提取到方法中来替换它。

资料来源:James Gosling,问答环节

于 2010-12-28T17:01:19.663 回答
210

Java 关键字列表指定了关键字goto,但它被标记为“未使用”。

它在原始 JVM 中(参见@VitaliiFedorenko 的回答),但随后被删除。它可能被保留为保留关键字,以防它被添加到更高版本的 Java 中。

如果goto不在列表中,并且稍后将其添加到语言中,则使用该词goto作为标识符(变量名称、方法名称等)的现有代码将中断。但是因为gotois 是一个关键字,所以这样的代码现在甚至无法编译,并且在不破坏现有代码的情况下,它仍然可以在以后实际执行某些操作。

于 2010-03-30T12:33:57.280 回答
157

关键字存在,但未实现。

我能想到的使用 goto 的唯一充分理由是:

for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        goto outsideloops; // to break out of both loops
    }
}
outsideloops:

在 Java 中,您可以这样做:

loops:
for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        break loops;
    }
}
于 2010-03-30T12:36:50.117 回答
43

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html

“关键字 const 和 goto 是保留的,即使它们当前没有使用。”

于 2010-03-30T12:32:40.980 回答
30

因此,如果语言设计者觉得有必要,它们总有一天会被使用。

此外,如果来自确实具有这些关键字的语言(例如 C、C++)的程序员错误地使用了它们,那么 Java 编译器可以给出有用的错误消息。

或者也许只是为了阻止程序员使用 goto :)

于 2009-08-26T12:40:02.483 回答
21

它们保留供将来使用(请参阅:Java 语言关键字

关键字 const 和 goto 是保留的,即使它们当前没有被使用。

Java中没有goto语句的原因可以在《Java语言环境》中找到

Java 没有 goto 语句。研究表明,goto 被(误)使用得更多,而不仅仅是“因为它在那里”。消除 goto 导致了语言的简化——例如,没有关于 goto 在 for 语句中间的影响的规则。对大约 100,000 行 C 代码的研究确定,大约 90% 的 goto 语句纯粹用于获得跳出嵌套循环的效果。如上所述,多级 break 和 continue 消除了对 goto 语句的大部分需求。

于 2010-03-30T12:35:44.413 回答
18

如何在 Java 中使用“继续”标签的一个示例是:

public class Label {
    public static void main(String[] args) {
        int temp = 0;
        out: // label
        for (int i = 0; i < 3; ++i) {
            System.out.println("I am here");
            for (int j = 0; j < 20; ++j) {
                if(temp==0) {
                    System.out.println("j: " + j);
                    if (j == 1) {
                        temp = j;
                        continue out; // goto label "out"
                    }
                }
            }
        }
        System.out.println("temp = " + temp);
    }
}

结果:

I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1
于 2013-04-11T10:53:16.397 回答
10

因为它不受支持,为什么你想要一个goto什么都不做的关键字或一个名为 的变量goto

尽管您可以使用break label;andcontinue label;语句来有效地执行goto操作。但我不会推荐它。

public static void main(String [] args) {

     boolean t = true;

     first: {
        second: {
           third: {
               System.out.println("Before the break");

               if (t) {
                  break second;
               }

               System.out.println("Not executed");
           }

           System.out.println("Not executed - end of second block");
        }

        System.out.println("End of third block");
     }
}
于 2009-08-26T12:40:27.240 回答
10

不,goto不使用,但您可以定义标签并在标签上留下一个循环。您可以使用breakcontinue后跟标签。因此,您可以跳出多个循环级别。看看教程

于 2010-03-30T12:39:18.327 回答
10

重要的是要了解该goto结构是程序员使用机器代码和汇编语言编程的时代遗留下来的。因为这些语言非常基础(例如,每条指令只做件事),程序控制流完全由goto语句完成(但在汇编语言中,这些被称为跳转分支指令)。

现在,尽管 C 语言相当低级,但它可以被认为是非常高级的汇编语言——C 中的每个语句和函数都可以很容易地分解为汇编语言指令。尽管 C 不是当今计算机编程的主要语言,但它仍然大量用于低级应用程序,例如嵌入式系统。因为 C 的函数与汇编语言的函数非常相似,所以只有goto包含在 C 中才有意义。

很明显,Java 是 C/C++ 的演变。Java 与 C 共享许多特性,但抽象了更多细节,因此只是以不同的方式编写。Java 是一种非常高级的语言,因此它根本不需要具有低级goto功能,例如函数、for、for each 和 while 循环执行程序控制流等更高级的构造。想象一下,如果您在一个函数中,并且对goto另一个函数中的标签执行了操作。当另一个函数返回时会发生什么?这个想法很荒谬。

这不一定回答为什么 Java 包含该goto语句但不会让它编译,但重要的是要知道为什么goto一开始就在较低级别的应用程序中使用它,以及为什么它只是没有意义在 Java 中使用。

于 2012-06-14T13:25:17.617 回答
9

不,谢天谢地,gotoJava 中没有。

goto关键字仅保留,但未使用(同样适用)const

于 2010-03-30T12:32:38.057 回答
7

不,goto在 Java 中不使用,尽管是保留字。对于const. 这两个都在 C++ 中使用,这可能是它们被保留的原因;这样做的目的可能是为了避免让 C++ 程序员迁移到 Java 时感到困惑,也可能是为了保留在 Java 的后续版本中使用它们的选项。

于 2010-03-30T12:34:09.773 回答
3

请注意,您可以将 goto 的大多数良性使用替换为

  • 返回

  • 休息

  • 打破标签

  • 扔进去 try-catch-finally

于 2009-08-26T18:14:35.353 回答
2

正如所指出的,gotoJava 中没有,但是保留了关键字,以防 Sungoto有一天想添加到 Java 中。他们希望能够在不破坏太多代码的情况下添加它,因此他们保留了关键字。请注意,他们在 Java 5 中添加了enum关键字,它也没有破坏那么多代码。

尽管 Java 没有goto,但它有一些结构与 的某些用法相对应goto,即能够breakcontinue具有命名循环。此外,finally可以认为是一种扭曲的goto

于 2010-03-30T12:36:17.003 回答
1

禁止声明同名变量。

例如 int i = 0, goto;

于 2009-08-26T12:40:25.960 回答
1

请参阅以下链接,其中显示了所有 java 保留字并告诉您它们添加了哪些版本。

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html

goto 是保留的,即使它当前没有被使用,但是永远不要说永远:)

于 2009-08-26T12:48:01.903 回答
1

它被认为是你不应该做的事情之一,但可能被列为保留字以避免开发人员混淆。

于 2010-03-30T13:28:55.447 回答
1

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto

如果你被告知 Java 中没有 goto 语句,那你就被愚弄了。事实上,Java 包含两层“源”代码。

于 2013-04-01T20:44:31.850 回答
1

我都不喜欢这goto两种方法,因为它通常会使代码的可读性降低。但是我确实相信该规则有例外(尤其是在词法分析器和解析器方面!)

当然,您始终可以将程序转换为类似汇编程序的东西,然后编写类似的东西,从而将您的程序带入 Kleene Normalform

int line = 1;
boolean running = true;
while(running)
{
    switch(line++)
    {
        case 1: /* line 1 */
                break;
        case 2: /* line 2 */
                break;
        ...
        case 42: line = 1337; // goto 1337
                break;
        ...
        default: running = false;
                break;
    }
}

(所以你基本上写了一个执行你的二进制代码的VM......line对应于指令指针)

这比使用 的代码更具可读性goto,不是吗?

于 2017-01-20T15:04:45.673 回答
1

是的,有可能,但不如 c# 好(我认为 c# 更好!)。goto 总是掩盖软件的观点是愚蠢和愚蠢的!可悲的是,java 至少没有 goto case xxx。

向前跳转:

 public static void main(String [] args) {
   myblock: {
     System.out.println("Hello");
     if (some_condition)
       break myblock; 
     System.out.println("Nice day");
   }
   // here code continue after performing break myblock
   System.out.println("And work");
 }

向后跳转:

 public static void main(String [] args) {
   mystart: //here code continue after performing continue mystart
   do {
     System.out.println("Hello");
     if (some_condition)         
       continue mystart; 
     System.out.println("Nice day");
   } while (false);
   System.out.println("And work");
 }
于 2020-09-16T17:20:13.823 回答
0

当然是关键字,但在源代码级别上没有使用。

但是如果你使用 jasmin 或其他低级语言,它被转换为字节码,那么“goto”就在那里

于 2016-09-25T14:43:54.687 回答
-1

因为虽然 Java 语言不使用它,但 JVM 字节码却使用它。

于 2013-01-29T16:18:14.887 回答
-6

goto不在Java中

你必须使用 GOTO 但它不能正常工作。在关键的 java 单词中它没有被使用。 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html

   public static void main(String[] args) {            
            GOTO me;
            //code;
            me:
            //code; 
            }   
   }
于 2017-08-10T13:10:50.647 回答