我应该避免使用Java标签语句吗?

今天,我有一个同事build议我重构我的代码,使用标签语句来控制我创build的2个嵌套for循环stream。 我从来没有使用过,因为我个人认为它们降低了程序的可读性。 如果论证足够稳固,我愿意改变主意。 人们对标签声明有何意见?

如果可以跳过两个循环(或包含switch语句的循环),则可以更容易地表示许多algorithm。 不要为此感到难过。 另一方面,这可能表明一个过于复杂的解决scheme。 所以退后一步,看看这个问题。

有些人更喜欢所有循环的“单一入口,单一出口”方式。 这就是说避免中断(并继续),并尽早返回循环。 这可能会导致一些重复的代码。

我强烈要避免的是引入辅助variables。 在状态内隐藏控制stream会增加混淆。

将标记的循环拆分为两种方法可能会很困难。 例外情况可能太重。 尝试一个单一的入口,单一的退出方式。

标签就像goto's:谨慎地使用它们,只有当他们使你的代码更快更重要,更易于理解,

例如,如果你处于六级深度的大循环中,并且遇到使剩余的循环没有意义完成的条件,那么在条件语句中有6个额外的陷阱门就没有必要提早退出循环。

标签(和goto's)不是邪恶的,只是有时候人们用坏的方式来使用它们。 大多数情况下,我们实际上是在编写我们的代码,所以对于您和下一位程序员来说,这是可以理解的。 使其超速是一个次要的问题(小心过早的优化)。

当标签(和goto的)被滥用,他们使代码更不可读,这会导致你和下一个开发人员的悲痛。 编译器不关心。

很less有时候你需要标签,他们可能会因为很less使用而感到困惑。 但是,如果你需要使用一个然后使用一个。

顺便说一句:这个编译和运行。

class MyFirstJavaProg { public static void main(String args[]) { http://www.javacoffeebreak.com/java101/java101.html System.out.println("Hello World!"); } } 

我很好奇听到你的替代标签是什么。 我认为这很可能归结为“尽早回归”与“使用variables来保持回报价值,只能在最后回报”的论点。

当你有嵌套循环时,标签是非常标准的。 他们真正减less可读性的唯一方法是,另一个开发人员以前从来没有见过他们,也不明白他们的意思。

我从来没有见过在Java代码中使用“在野外”的标签。 如果你真的想要打破嵌套循环,看看你是否可以重构你的方法,以便早期返回语句做你想要的。

从技术上讲,我想早期回报和标签之间没有太大的区别。 实际上,几乎每个Java开发者都看到了一个早期的回报,并且知道它的作用。 我想很多开发者至less会被一个标签惊讶,可能会感到困惑。

我曾在学校教过单一入学/单一退学的正统课程,但是我从此开始认识到早期回归陈述和循环作为一种简化代码并使之更加清晰的方法。

我想用新的for-each循环,标签可以很清楚。

例如:

 sentence: for(Sentence sentence: paragraph) { for(String word: sentence) { // do something if(isDone()) { continue sentence; } } } 

我认为,通过让你的标签与新的for-eachvariables相同,看起来很清楚。 事实上,也许Java应该是邪恶的,为每个variables添加隐式标签

我使用Java标记的循环来实现Sieve方法来查找质数(对于项目Eulermath问题之一完成),使其比嵌套循环快10倍。 例如,如果(某些条件)回到外部循环。

 private static void testByFactoring() { primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) { int toTest = m_toFactor[ctr]; for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) { // max (int) Math.sqrt(m_numberToTest) + 1 iterations if (toTest != m_divisors[ctr2] && toTest % m_divisors[ctr2] == 0) { continue primes; } } // end of the divisor loop } // end of primes loop } // method 

我问了一个C ++程序员有多糟糕的标签循环,他说他会谨慎地使用它们,但偶尔也会派上用场。 例如,如果您有3个嵌套循环,并且对于某些情况,您想要返回到最外层的循环。

所以他们有他们的用途,这取决于你想解决的问题。

我会在某些地方争论他们,我发现他们在这个例子中特别有用:

 nextItem: for(CartItem item : user.getCart()) { nextCondition : for(PurchaseCondition cond : item.getConditions()) { if(!cond.check()) continue nextItem; else continue nextCondition; } purchasedItems.add(item); } 

我从来没有在我的代码中使用标签。 我更喜欢创build一个守卫并将其初始化为null或其他不寻常的值。 这个守卫往往是一个结果对象。 我没有看到任何使用标签的同事,也没有在我们的存储库中find任何标签。 这真的取决于你的编码风格。 在我看来,使用标签会降低可读性,因为它不是一个常见的构造,通常不会在Java中使用。

是的,你应该避免使用标签,除非有特定的理由使用它(简化algorithm实现的例子是相关的)。 在这种情况下,我会build议添加足够的评论或其他文档来解释背后的原因,以便有人不会迟到,并将其改为“改善代码”或“消除代码异味”的概念或一些其他潜在的BS借口。

我会把这类问题等同于决定何时应该或不应该使用三元论。 主要的原因是它会阻碍可读性,除非程序员非常小心地以合理的方式命名,否则使用标签等约定会使事情变得更糟。 假设使用'nextCondition'和'nextItem'的例子使用了'loop1'和'loop2'作为他的标签名称。

个人标签是在Assembly,BASIC以及其他类似的有限语言之外,对我来说没有多大意义的function之一。 Java有更多的常规/常规循环和控制结构。

我发现标签在testing中有时是有用的,分开了通常的设置,练习和validation阶段和组相关的陈述。 例如,使用BDD术语:

 @Test public void should_Clear_Cached_Element() throws Exception { given: { elementStream = defaultStream(); elementStream.readElement(); Assume.assumeNotNull(elementStream.lastRead()); } when: elementStream.clearLast(); then: assertThat(elementStream.lastRead()).isEmpty(); } 

您的格式select可能会有所不同,但其核心思想是,在这种情况下,标签在组成testing的逻辑部分之间提供了明显的区别,优于评论。 我认为Spock库build立在这个特性上来声明它的testing阶段。