我正盯着2001年的一些旧代码,并发现了这句话:
else {
do {
int c = XMLDocumentFragmentScannerImpl.this.scanContent();
if (c == 60) {
XMLDocumentFragmentScannerImpl.this.fEntityScanner.scanChar();
XMLDocumentFragmentScannerImpl.this.setScannerState(1);
break label913;
}
Run Code Online (Sandbox Code Playgroud)
我以前从未见过这个,并在这里发现了带标签的断点:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
这基本上不起作用goto吗?使用它是否是好的做法?这让我感到不安.
Tho*_*mas 105
不,它不像是一个goto,因为你不能"去"控制流程的另一部分.
从您链接的页面:
break语句终止带标签的语句; 它不会将控制流转移到标签上.控制流将在标记(终止)语句之后立即转移到语句.
这意味着您只能断开当前正在执行的循环.
考虑这个例子:
first:
for( int i = 0; i < 10; i++) {
second:
for(int j = 0; j < 5; j ++ )
{
break xxx;
}
}
third:
for( int a = 0; a < 10; a++) {
}
Run Code Online (Sandbox Code Playgroud)
您可以xxx用first或替换second(以打破外部或内部循环),因为当您执行两个循环时,当您按下该break语句时,替换xxx为third将无法编译.
Nat*_*hes 13
它并不像goto因为它只将控制权发送到标记语句的末尾(通常是循环结构).令人goto不可思议的是,它是任意位置的任意分支,包括在方法源中找到更高位置的标签,因此您可以拥有自行生成的循环行为.Java中的标签中断功能不允许这种疯狂,因为控制只会前进.
我大约12年前才使用它一次,在我需要打破嵌套循环的情况下,结构越多的替代方案就会在循环中进行更复杂的测试.我不建议使用它很多,但我不会把它标记为自动坏代码气味.
在阅读本答复的其余部分之前,请阅读Go To Statement Considered Harmful.如果您不想完整阅读,我认为这是关键点:
肆无忌惮地使用go to语句会立即导致很难找到一组有意义的坐标来描述过程进度.
或者换句话说,问题goto在于程序可以在代码块的中间到达,而程序员不需要了解程序状态.标准的面向块的构造被设计为清楚地描绘状态转换,标记break的意图是将程序带到特定的已知状态(在包含标记的块之外).
在现实世界的命令式程序中,状态没有被块边界清楚地描述,因此标记是否break是一个好主意是值得怀疑的.如果块改变了从块外部可见的状态,并且有多个点退出块,则标记break等同于基元goto.唯一的区别是,不是在具有不确定状态的块中间着陆的可能性,而是启动具有不确定状态的新块.
所以,一般来说,我会认为标记break为危险.在我看来,这是一个标志,应该将块转换为一个函数,对封闭范围的访问权限有限.
但是,这个示例代码显然是解析器生成器的产物(OP评论说它是Xerces源代码).而解析器生成器(或一般的代码生成器)通常会对它们生成的代码自由,因为它们具有完美的状态知识,人类不需要理解它.
总是可以break用新方法替换.
考虑检查两个列表中的任何公共元素的代码:
List list1, list2;
boolean foundCommonElement = false;
for (Object el : list1) {
if (list2.contains(el)) {
foundCommonElement = true;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样重写它:
boolean haveCommonElement(List list1, List list2) {
for (Object el : list1) {
if (list2.contains(el)) {
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
当然,要检查两个列表,最好使用之间的共同元素list1.retainAll(new HashSet<>(list2))的方法来做到这一点,在O(n)与O(n)额外的内存,或者在两个列表进行排序O(n * log n),然后找到共同的元素O(n).
| 归档时间: |
|
| 查看次数: |
53968 次 |
| 最近记录: |