goto语句一直被人所诟病,说它使得代码结构复杂化,但是语言设计者们还是没有放弃goto这个功能强大的语句。Java以面向对象所著称也没能够放弃goto,而是把它当做保留字,但是并未在语言中得到正式使用。

然而,从Java的break和continue这两个关键字的身上,我们依然能够看出一些goto的影子。

下面是《Thinking In Java 4th》中关于“goto”的介绍:

臭名昭著的“goto”

goto 关键字很早就在程序设计语言中出现。事实上,goto 是汇编语言的程序控制结构的始祖:“若条件A,则跳到这里;否则跳到那里”。若阅读由几乎所有编译器生成的汇编代码,就会发现程序控制里包含了许多
跳转。然而,goto 是在源码的级别跳转的,所以招致了不好的声誉。若程序总是从一个地方跳到另一个地方,还有什么办法能识别代码的流程呢?随着Edsger Dijkstra 著名的“Goto 有害”论的问世,goto 便从此
失宠。

事实上,真正的问题并不在于使用goto,而在于goto 的滥用。而且在一些少见的情况下,goto 是组织控制流程的最佳手段。

尽管goto 仍是Java 的一个保留字,但并未在语言中得到正式使用;Java 没有goto。然而,在break 和continue 这两个关键字的身上,我们仍然能看出一些goto 的影子。它并不属于一次跳转,而是中断循环语句的一种方法。之所以把它们纳入goto 问题中一起讨论,是由于它们使用了相同的机制:标签。

Java中的标签

“标签”是后面跟一个冒号的标识符,就象下面这样:
label1:

对Java 来说,唯一用到标签的地方是在循环语句之前。进一步说,它实际需要紧靠在循环语句的前方——在标签和循环之间置入任何语句都是不明智的。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另
一个循环或者一个开关。这是由于break 和continue 关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
label1:
外部循环{
内部循环{
//...
break; //1
//...
continue; //2
//...
continue label1; //3
//...
break label1; //4
}
}

在条件1 中,break 中断内部循环,并在外部循环结束。在条件2 中,continue 移回内部循环的起始处。但在条件3 中,continue label1 却同时中断内部循环以及外部循环,并移至label1 处。随后,它实际是继续循环,但却从外部循环开始。在条件4 中,break label1 也会中断所有循环,并回到label1 处,但并不重新进入循环。也就是说,它实际是完全中止了两个循环。

代码测试(java)

一下代码均已在jdk1.6版本中测试通过

break语句测试

1
2
3
4
5
6
7
8
9
10
11
12
public static void testLabel()
{for (int i = 0; i < 2; i++) {System.out.println("L1----"+i);for (int j = 0; j < 4; j++) {if (j == 2) {break;}System.out.println("--------L2---"+j);}}
}

执行结果:

1
2
3
4
5
6
L1----0
--------L2---0
--------L2---1
L1----1
--------L2---0
--------L2---1

这个代码中break直接中断内部的for循环。

break+label语句测试

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void testLabel3()
{
label1:for (int i = 0; i < 2; i++) {System.out.println("L1----"+i);for (int j = 0; j < 4; j++) {if (j == 2) {break label1;}System.out.println("--------L2---"+j);}}
}

执行结果:

1
2
3
L1----0
--------L2---0
--------L2---1

在这个代码中break中断标签label1处的外部for循环。

continue语句测试

1
2
3
4
5
6
7
8
9
10
11
public static void testLabel2() {for (int i = 0; i < 2; i++) {System.out.println("L1----"+i);for (int j = 0; j < 4; j++) {if (j == 2) {continue;}System.out.println("--------L2---"+j);}}}

执行结果:

1
2
3
4
5
6
7
8
L1----0
--------L2---0
--------L2---1
--------L2---3
L1----1
--------L2---0
--------L2---1
--------L2---3

在这个代码中continue中断掉内部的for循环后继续执行内部for循环。

continue+label语句测试

1
2
3
4
5
6
7
8
9
10
11
12
13
public static void testLabel4()
{
label1:for (int i = 0; i < 2; i++) {System.out.println("L1----"+i);for (int j = 0; j < 4; j++) {if (j == 2) {continue label1;}System.out.println("--------L2---"+j);}}
}

执行结果:

1
2
3
4
5
6
L1----0
--------L2---0
--------L2---1
L1----1
--------L2---0
--------L2---1

在这个代码中continue中断掉内部的for循环后继续执行跳到标签label1处的外部for循环,继续执行。

Author: crane-yuan

Link: https://crane-yuan.github.io/2016/08/30/The-reserved-word-of-goto/

License: 知识共享署名-非商业性使用 4.0 国际许可协议

Java中被搁置的“goto”保留字相关推荐

  1. java类似goto_原来java中也有类似goto语句的标签啊--java label标签

    goto语句的危害: goto语句是在源码级上的跳转,这使其招致了不好的声誉.若一个程序总是从一个地方跳到另一个地方,还有什么办法来控制程序的流程. java中的"goto": 虽 ...

  2. Java中goto用法

    臭名昭著的goto 第一次见到goto应该在<C programming>这本书里,那是相当地震惊:想起之前从循环深处往出跳的那个费劲. 废话不多说,咱这里先用上感受一下: /* 一个整数 ...

  3. Java中的goto

    一. Java中的goto关键字 在C/C++中,goto常被用于跳出多重循环.但goto 语句的使用往往会使程序的可读性降低,所以 Java 不允许 goto 跳转.实际上,自从"goto ...

  4. Java中常见的单词

    abstract (关键字)             抽象 ['.bstr.kt]  access                            vt.访问,存取 ['.kses]'(n.入口 ...

  5. java中一些常用的英语

     abstract (关键字  ) 抽象  ['.bstr.kt]  access vt.访问,存取  ['.kses]'(n.入口,使用权)  algorithm n.算法  ['.lg.rie ...

  6. java中常见的英语单词

    abstract (关键字)             抽象 ['.bstr.kt]  access                            vt.访问,存取 ['.kses]'(n.入口 ...

  7. 互联网名词 java中单词解释

    SaaS是Software-as-a-service(软件即服务)的简称: 网络广告专业用语书写规范及解释 互联网营销中充满了各种名字,缩写.同学们是不是经常因此而头晕呢?下面我们给大家整理出来了比较 ...

  8. java由goto_在java中goto的目的

    本问题已经有最佳答案,请猛点这里访问. 我知道EDCOX1 0是Java中的关键字.另外,从wiki,我可以摘录到,"它没有被使用,也没有任何功能". 我想知道,如果goto没有用 ...

  9. java中break,continue,標籤實現goto效果(編程思想)

    goto 編程語言中一開始就有goto關鍵詞了.事實上,goto起源於彙編語言的進程控制:"若條件A成立,則調到這裏:否則跳到那裏". goto語句時在源碼級別上的跳轉,這導致了其 ...

最新文章

  1. prometheus+node_exporter+grafana实践
  2. ffmpeg 源码学习
  3. java heroku_Heroku运行Java
  4. BootStrap笔记-文字排版
  5. 4g模块注册上网 移远_物联网模组龙头移远通信
  6. VSTO 实现word的多级列表功能
  7. css表格做日历,CSS 制作有弹性的日历表
  8. HTML页面基本结构
  9. 西安交大计算机2000年山西专业录取分数,西安交通大学分数线-2017年各省各专业录取分数线(历年分数线查询)...
  10. 百分之99的人都不知道的Python爆破ZIP文件
  11. elementUI的tree组件搜索过滤,可识别拼音,且不区分大小写
  12. Greenplum小把戏 - 官方布尔类型转换为文本类型(bool to text)的进步
  13. 关于YunFile网盘的一些使用技巧与心得
  14. 【1月英语—罗塞塔之爱】
  15. 监控摄像头的测试方法
  16. 到底人工智能前景好不 首选哪个开发语言好
  17. Opencv学习笔记 - 使用opencvsharp和决策树进行训练和预测
  18. C# FIR滤波器(含低通、高通、带通、带阻)
  19. 音视频学习笔记1--音视频基础知识(1)
  20. 风河产品license介绍(Wind River Product Licensing video)

热门文章

  1. 从技术角度谈一谈,我参与设计开发的手Q春节红包项目--转
  2. mysql 异常处理实例
  3. MySQL——基于CASE WHEN的常用查询
  4. 电商双11已臻巅峰,众筹的双11才刚刚开始
  5. 李开复:走向全球的两大路径,中美何以各占其一
  6. android webservices 返回多行多列数据,Pandas: 如何将一列中的文本拆分为多行?
  7. 每日一博 - 使用环形队列实现高效的延时消息
  8. C++五子棋(二)——游戏界面与棋子渲染
  9. c++ 不允许使用抽象类类型的对象_Java中日期API的使用总结
  10. 学习笔记Flink(四)—— Flink基础API及核心数据结构