我对此很困惑。我们中的大多数人都被告知Java中没有任何GOTO语句。
但我发现它是Java中的关键字之一。在哪里可以使用?如果它不能被使用,那么为什么它包含在Java中作为关键字呢?
- 只是一句忠告:永远不要用goto
- Dijkstra大师说:"去声明被认为是有害的。"看看这个:stackoverflow.com/questions/46586/go to仍然被认为是有害的‌&误8203;ful
- 然后有"去有害的陈述被认为有害"和"去有害的陈述被认为有害"被认为有害?非常递归,这个模因。
- 伙计们,大家都知道他哥多是邪恶的,但这不是问题的答案,是吗?
- "Goto"总是邪恶的,就像"Goto Work"或"Goto School"一样;
- 不仅是goto,const也是保留的。
- @安德烈亚斯:谢谢!你刚刚帮我在我的销售代表简介里填上了"关于我"。-)
- 真正的原因是"g**o"这个词在大多数编程语言中被认为是淫秽的。Java设计者只是在保护无辜的年轻程序员免受破坏的影响。(-)
- Java中GOTO语句替换的可能副本
- 不要被破坏。但请访问github.com/footlosejava/javagoto
- 这里有几个答案说明它是为将来使用而保留的,这是不正确的。事实上,高斯林从一个很早的版本中去掉了它,只保留了保留的关键字。
- 对哥特人的女巫猎杀在我的生活中催生了一些最令人恼火的时刻。我见过人们通过在函数中隐藏功能来扭曲C代码,在多个嵌套循环中放置荒谬的退出逻辑,或者做任何形式的过度工程,只是为了避免有人在代码评审中批评他们的代码。这条规则,连同"你必须避免多重回报"的谣言,都是胡说八道。有时goto会降低维护性。有时Goto会使事情更易于维护。我真希望这场女巫狩猎会在80年代死去。
- 自从我学习编程2年以来,这是我第一次看到goto的良好使用,我的意思是,它可能很有用。或者说:为什么要首先删除一个特性?
- @user4229245(你已经不存在了,这是为了子孙后代)够有趣的:goto是执行我们代码的处理器所知道的唯一的分支指令,而我们,程序员,唯一被禁止使用的分支指令……
詹姆斯戈斯林在支持goto语句的情况下创建了最初的JVM,但随后他删除了这个不必要的特性。不需要goto的主要原因是,通常可以用可读性更强的语句(如break/continue语句)或将一段代码提取到一个方法中。
来源:James Gosling,问答环节
- "…或者通过将一段代码提取到一个方法中"——如果没有适当的尾调用消除,这必须非常酷。
- 有时,明智地使用goto是表达某种东西最容易和最清晰的方式,因此将它强制转换成其他东西的性能是不可读的。
- @goto的重复数据消除程序的使用虽然明智,但总是容易出错。
- "去重复器":GOTO在C++中考虑良好实践的唯一用途是由中断/继续支持。
- Goto在Java中是一个保留关键字非常重要,因为它阻止人们命名标签"Goto:"。
Java关键字列表指定EDCOX1的1个关键字,但它被标记为"未使用"。
它在原始的JVM中(见@vitalifedorenko的回答),但随后被删除。它可能被保留为一个保留关键字,以防它被添加到Java的后期版本中。
如果goto不在列表中,并且后来被添加到语言中,那么使用goto一词作为标识符(变量名、方法名等)的现有代码将中断。但是,由于goto是一个关键字,这种代码在目前甚至不会编译,而且在以后仍然有可能让它实际做一些事情,而不破坏现有的代码。
- 实际上,主要原因有点不同(见下面我的答案)。
- 这是一个很好和有趣的信息,但它不能解释为什么它仍然是一个保留关键字。
- @托马斯,你没描述为什么要保留它吗?它是一个关键字,所以现在不能使用;以后goto可以在不引起问题的情况下重新启动。如果它不是保留字,现在就可以用来生成代码(int goto=2;),如果引入goto,代码就会中断。
关键字存在,但未实现。
使用goto的唯一好理由是:
1 2 3 4 5 6 7
| 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: |
在爪哇,你可以这样做:
1 2 3 4 5 6 7
| loops:
for (int i = 0; i < MAX_I; i++) {
for (int j = 0; j < MAX_J; j++) {
// do stuff
break loops;
}
} |
- 这不会只破坏内部循环吗?
- @zolt&n否-它将代码重定向到标签,就在第一个循环之前。
- @还有,不完全是。标签标记了外部循环。那么,break loops的意思是"脱离称为loops的循环"。回想起来,该标签的更好名称可能是outer。
- 在我看来,这是迄今为止最好的答案。
- "使用goto的唯一好理由"需要无条件无限循环的快速而肮脏的小程序大量使用goto。使用while (true) {…}是过度杀伤。goto经常因其不当使用而受到指责,但我认为不必要的布尔文字比较比goto更糟。
- 如何实现一个小的硬编码FSM?
- 我同意。我需要无数次goto来破坏嵌套循环。我相信,它只对这个有用。感谢使用break LABEL;语法。我不熟悉!
- 循环标签不应该在循环之后吗?
- @gc在阅读你上面的评论时,应该解释为什么它是这样写的:"标签标记了外循环。"那么break循环意味着"从称为循环的循环中中断"。
- 旧的,但是是金柱。我从来没有在我做过的任何Java项目中看到过这种情况。+ 1
- 我最近发现,这种标记技术与continue LABEL;声明相结合也非常有用。这样你就可以继续一个外卧环。
http://java.sun.com/docs/books/tutorial/java/nutsandbolts//u keywords.html
"The keywords const and goto are
reserved, even though they are not
currently used."
- "unsigned"甚至不存在!(叹气)
- 这是有意义的,因为Java中的所有原始类型都是签名的。
- @不是全部。"char"是一个基元类型,它是无符号的。
因此,如果语言设计者觉得有必要,他们有一天可以使用。
此外,如果来自那些拥有这些关键字(例如,C,C++)的程序员错误地使用它们,那么Java编译器可以提供有用的错误消息。
或者只是为了阻止程序员使用goto:)
- 合理!!)
- Java中缺少的Goto功能应该是足够的理由不使用GOTO——没有必要将其保留为关键字。遵循你的逻辑,所有的东西都是关键字,因为它可以被其他语言使用和/或Java设计者可以在将来使用它。
- 我不认为我的逻辑意味着一切都是关键字。在许多编程语言中使用的一组小关键字可以在Java中有效地检测和处理。Java保留了EDCOX1 0和EDCOX1 1,反映了它的C/C++遗产,但它们仍然未实现(尽管一直存在着关于实现后者的争论)。一对更像assert和enum的夫妇最初并没有被保留,但考虑到他们已经被实施,也许应该保留。但事后诸葛亮是件好事。
- 仅供参考:合并自stackoverflow.com/questions/1334376/goto-keyword-in-java
它们保留以供将来使用(参见:Java语言关键字)
The keywords const and goto are reserved, even though they are not currently used.
Java中没有GOTO语句的原因可以在"Java语言环境"中找到:
Java has no goto statement. Studies illustrated that goto is (mis)used more often than not simply"because it's there". Eliminating goto led to a simplification of the language--there are no rules about the effects of a goto into the middle of a for statement, for example. Studies on approximately 100,000 lines of C code determined that roughly 90 percent of the goto statements were used purely to obtain the effect of breaking out of nested loops. As mentioned above, multi-level break and continue remove most of the need for goto statements.
- goto是保留的,但不供将来使用。
- @希望如此。-)
如何在Java中使用"继续"标签的例子是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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 );
}
} |
结果:
1 2 3 4 5 6
| I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1 |
不,不使用goto,但您可以定义标签并在标签上留下一个循环。您可以使用break或continue后跟标签。所以您可以跳出多个循环级别。看看这个教程。
重要的是要理解,goto结构是程序员用机器代码和汇编语言编程时遗留下来的。由于这些语言非常基础(如,每个指令只做一件事),所以程序控制流完全是用goto语句完成的(但在汇编语言中,这些指令称为跳转或分支指令)。
现在,虽然C语言是相当低级的,但它可以被认为是非常高级的汇编语言——C中的每个语句和函数都可以很容易地分解为汇编语言指令。虽然C语言不是当今计算机编程的主要语言,但它仍然大量应用于低层应用,如嵌入式系统。因为C的函数非常接近于汇编语言的函数,所以把goto包含在C中才有意义。
很明显,Java是C/C++的演进。Java与C共享很多特性,但是抽象了更多的细节,因此只是写得不一样。Java是一种非常高级的语言,所以简单地说,当像函数、每个循环和while循环这样的更高级的结构执行程序控制流时,就不必有像EDCOX1 0级这样的低级特征。想象一下,如果您在一个函数中,并将goto转换为另一个函数的标签。当另一个函数返回时会发生什么?这个想法很荒谬。
这不一定回答为什么Java包含EDCOX1的0Ω语句,但不会让它编译,但重要的是要知道为什么EDOCX1 0的引用在最初的地方被使用,在较低级别的应用程序中,以及为什么在Java中使用它是没有意义的。
- "程序控制流程完全由goto完成"。好吧,不一定是无条件的goto。
- 在C/C++中,用"Goto"从一个函数跳到另一个函数的标签也是不可能的。C/C++中的GOTO被限制为单个功能块。
- "当更高层次的构造时,根本不需要像goto这样的低层次特性"——记住"必要性和充分性"。只是"没有必要"。因此没有理由。原因是:如果你想跳转到"可执行代码",但Java是字节码,因此"不可执行",则"Goto"作为汇编程序的JMPS、BNE和更多的"高级"替代是合理的。;-)
不,谢天谢地,Java中没有EDCOX1 1Ω。
goto关键字只保留,不使用(const也一样)。
- 我能知道这里的"保留"是什么意思吗?如果在代码中使用goto和const不是一个好的实践,为什么他们要保留它?你能解释一下吗?
- @sri kumar:见@applechuver的答案,它存在,但没有实现。
- @sri kumar:保留的关键字防止它们被用作变量名或类似的名称。这样,这些关键字可以在Java的未来版本中实现,而不会破坏原本可以使用它们的旧源代码。
因为它不受支持,为什么您要一个没有任何作用的goto关键字或一个名为goto的变量?
尽管您可以使用break label;和continue label;语句来有效地执行goto所做的操作。但我不推荐。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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");
}
} |
- -1为什么不允许我有一个名为goto的变量或方法?
- 因为它在编程领域中有意义,它不适用于Java。这也是一个糟糕的变量名选择。
- 那印刷、阅读等词怎么办?
- 变量"print"的用途是什么?您提到的单词更像方法名,而不是变量或关键字。
- 1:首先,仅仅因为Java不支持"Goto"流控制语句,这并不意味着它有"Goto"关键字,它没有做任何事情。其次,"goto"可能是一个糟糕的变量名,但它可以是一个优秀的方法名,我们不能使用它,因为"goto"是一个关键字。第三,"break label"和"continue label"的存在有很好的理由,所以"not recommending it"不是很有用。第四,由于Sun说它"目前没有使用",这很可能意味着他们曾经计划实施,但当他们决定不使用时,不想删除关键字。
- "不推荐"=风格不好——不是说break和continue不好
- @Vojislavstojkovic那简直是胡说八道。1)这就是为什么它什么也不做是因为它不支持它。根据JLS EDCOX1第6条,这意味着"我们不使用它,所以如果你来自C++背景,我们根本不会让你使用它。"2)goto是一个糟糕的方法名。对不起的。3)建议中断并继续,但不以此处使用的方式。4)"最有可能"[需要引文]。
- 仅供参考:合并自stackoverflow.com/questions/1334376/goto-keyword-in-java
不,EDCOX1 1Ω在Java中不使用,尽管它是保留字。对于const也是如此。这两种都在C++中使用,这可能是它们被保留的原因;其意图可能是避免混淆C++程序员迁移到Java,也可能保留在以后的Java修改中使用它们的选项。
- 我真的希望至少在不久的将来不会支持goto;)
- @博佐:嗯,它可以用于一些巧妙的新特性,而这些新特性与旧的"有害的"goto毫无关系。
- 我真的很想要goto。
正如所指出的,Java中没有EDCOX1 1,但是在Sun感觉像一天添加EDCOX1,1,to Java的情况下,关键字被保留了。他们希望能够在不破坏太多代码的情况下添加它,因此他们保留了关键字。注意,在Java 5中,他们添加了EDCOX1,17,}关键字,也没有破坏太多代码。
虽然Java没有EDCOX1的1度,但它有一些与goto的用法相对应的结构,即EDCOX1×20和EDCOX1,21,具有命名的循环。另外,finally可以看作是一种扭曲的goto。
禁止声明具有相同名称的变量。
例如int i = 0, goto;
- 但是为什么呢?为什么不允许我们做这些声明?
- 仅供参考:合并自stackoverflow.com/questions/1334376/goto-keyword-in-java
请参阅下面的链接显示所有Java保留字,并告诉您它们添加了哪些版本。
http://java.sun.com/docs/books/tutorial/java/nutsandbolts//u keywords.html
goto是保留的,即使它当前没有被使用,也不要说永远不会。)
- 仅供参考:合并自stackoverflow.com/questions/1334376/goto-keyword-in-java
请注意,您可以用
- 不应将异常用于流控制
- 异常用于流控制,但应仅用于异常情况。例如,goto在c中的一个用途是错误处理,特别是在涉及清理的情况下。
- @斯塔布鲁,你把我说的话都说出来了。引发异常的是控制流。实际上,在C中,您可以通过setjmp/longjmp在一定程度上干净地实现异常处理,方法是确保首先将setjmp设置为处理代码,然后对异常执行longjmp()。
- 我想做一个if检查,如果为真,跳过方法的一半。如果不去,我必须用一个巨人。在我看来,这很难看,因为太多的妄想会造成混乱。
- @你可以试试看。
- 注意,如果可以用continue替换,我不会认为goto是良性的,因此continue被故意从列表中删除。
- @我想跳过一半的方法,而不是整个方法。
- @那么您应该重新构造代码。
我也不喜欢goto,因为它通常会降低代码的可读性。但是,我相信这个规则有例外(特别是在涉及到lexer和parsers的时候!)
当然,通过将程序翻译成类似汇编程序的格式,然后编写类似于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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;
}
} |
(所以你基本上写了一个执行二进制代码的虚拟机…其中line对应指令指针)
这比使用goto的代码更可读,不是吗?
- 下一个问题,"python中有switch语句吗?"
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html jvms-6.5.goto
如果有人告诉你Java中没有GOTO语句,你就被愚弄了。实际上,Java由两层"源代码"组成。
- 这就像是说任何语言都有一个goto,因为它下面的汇编代码中存在一个无条件的分支。在字节码中有GOTO并不意味着Java中有一个GOTO,因为"在Java中"意味着"在Java语言中",字节码不是一个源层。
- "TMG1024","在Java中"也可以被解释为"Java平台"。Java编译器需要产生Java字节码或输出不能在Java平台JVM中工作。例如,C++不指定编译输出,编译器可以自由地生成任何形式的机器代码(或任何其他代码)。Java字节码编程的应用程序可以称为"Java应用程序",但是机器代码编程的应用程序不能称为"C++应用程序"。
- 我完全了解java bytecode是什么。我在1996第一次用Java编码。您可以使用其他语言生成JVM的Java字节码。我要纠正的是这样一个观点,即有两层源代码。没有。您有Java源代码,并将其编译为Java字节代码(由JVM执行),这不是源代码的附加层。仅仅因为字节码中有一个"Goto"并不意味着爪哇有一个"Goto"。Java已命名为"断点",命名为"继续",但没有"GOTO"。
- @TGM1024我被否决票吵醒了:)很容易看起来,自从你最后一次发表评论,你的资历令人印象深刻,我就失去了争论。我的观点是,用Java字节码编程是非常可能的。为了向您保证,这里甚至还有一个问题:stackoverflow.com/question s/3150254/&hellip;
它被认为是您不需要做的事情之一,但可能被列为一个保留字,以避免开发人员混淆。
因为Java语言不使用它,JVM字节码确实如此。
- 那为什么语言没有load关键字呢?
- @Gribnit,在字节码中有goto本身并不意味着对上层保留字有任何意义。
当然,它是关键字,但不用于源代码级别。
但是如果你使用Jasmin或者其他低级语言,它被转换成字节码,那么"goto"就存在了。
Goto不是Java
你必须用goto但它不能正常工作。在关键的Java字中,它不被使用。http://docs.oracle.com/javase/tutorial/java/nutsandbolts//u keywords.html
1 2 3 4 5 6 7
| public static void main (String[] args ) {
GOTO me ;
//code;
me :
//code;
}
} |