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

时间:2020-03-05 18:48:25  来源:igfitidea点击:

今天,我有一个同事建议我重构代码,以使用label语句来控制我创建的2个嵌套的for循环的流程。我以前从未使用过它们,因为我个人认为它们会降低程序的可读性。如果论点足够扎实,我愿意改变使用它们的想法。人们对标签陈述有何看法?

解决方案

回答

我很想知道我们可以替代标签的是什么。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。我认为这几乎可以归结为"尽早返回"与"使用变量来保存返回值,并且只在最后返回"的论点。

当我们有嵌套循环时,标签是非常标准的。它们真正降低可读性的唯一方法是,当另一个开发人员以前从未见过它们并且不了解它们的含义时。

回答

我从不在代码中使用标签。我更喜欢创建一个防护并将其初始化为null或者其他异常值。该防护通常是结果对象。我还没有看到任何同事使用标签,也没有在我们的存储库中找到任何同事。这实际上取决于编码风格。在我看来,使用标签会降低可读性,因为它不是常见的构造,并且通常不在Java中使用。

回答

如果我们可以跳过两个循环(或者一个包含switch语句的循环),则许多算法的表达会更容易。不要为此感到难过。另一方面,它可能表明解决方案过于复杂。因此,退后一步,看看问题所在。

有些人喜欢在所有循环中使用"单入口单出口"方法。也就是说,完全避免了循环的中断(并继续)和提早返回。这可能会导致某些重复的代码。

我强烈避免做的是引入辅助变量。将控制流隐藏在状态内会增加混乱。

将标记的循环分为两种方法可能很困难。异常可能太重了。尝试一次进入,一次退出方法。

回答

标签就像goto的标签:谨慎使用标签,只有在它们使代码更快,更重要,更易于理解时,

e.g., If you are in big loops six levels deep and you encounter a condition that makes the rest of the loop pointless to complete, there's no sense in having 6 extra trap doors in your condition statements to exit out the loop early.

标签(和goto的标签)不是邪恶的,只是有时人们以不良的方式使用它们。大多数情况下,我们实际上是在尝试编写代码,因此我们和随之而来的下一个程序员都可以理解。使其超快是次要问题(请提防过早的优化)。

当滥用标签(和goto的标签)时,它们会使代码的可读性降低,从而给我们和下一个开发人员带来麻烦。编译器不在乎。

回答

我从未见过在Java代码中"野外使用"的标签。如果我们真的想打破嵌套循环,请查看是否可以重构方法,以便早期return语句可以满足要求。

从技术上讲,我认为提早退货和贴标签之间没有太大区别。但是,实际上,几乎每个Java开发人员都已经看到了早期回报,并且知道它做了什么。我想许多开发人员至少会对标签感到惊讶,并且可能会感到困惑。

在学校里,我曾教过单一入口/单一出口正统学,但是从那以后,我开始欣赏早期的return语句和打破循环,从而简化了代码并使其更加清晰。

回答

我认为使用新的for-each循环,标签可以非常清晰。

例如:

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

我认为通过在新的for-each中使标签与变量相同,可以很清楚地看出这一点。实际上,也许Java应该是邪恶的,并为每个变量添加隐式标签,呵呵

回答

我会在某些位置支持它们,在此示例中我发现它们特别有用:

nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}

回答

在极少数情况下,我们需要标签,并且由于很少使用它们,它们可能会造成混淆。但是,如果我们需要使用一个,请使用一个。

顺便说一句:编译并运行。

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

回答

我使用Java标记的循环来实现Sieve方法的方法来查找素数(针对项目Euler数学问题之一),这使其比嵌套循环快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个嵌套循环,并且对于某些条件,则要返回最外层循环。

因此它们有其用途,这取决于我们要解决的问题。