关于Java Coding标准/最佳实践:Java Coding标准/最佳实践-中断/继续标签的命名约定

关于Java Coding标准/最佳实践:Java Coding标准/最佳实践-中断/继续标签的命名约定

Java Coding standard / best practices - naming convention for break/continue labels

有时,标记为中断或继续可使代码更具可读性。

1
2
3
4
5
6
OUTERLOOP: for ( ;/*stuff*/; ) {
    //...lots of code

    if ( isEnough() ) break OUTERLOOP;
    //...more code
}

我想知道标签的通用约定是什么。 全部大写? 第一个帽子?


我不明白这个"不使用标签"规则的来源。当执行非平凡的循环逻辑时,中断或继续的测试并不总是在周围代码块的末尾整齐地进行。

1
2
3
4
5
6
7
8
9
10
11
outer_loop:
for (...) {
  //  some code
  for (...) {
    //  some code
    if (...)
      continue outer_loop;
    //  more code
  }
  //  more code
}

是的,这种情况一直在发生。人们建议我改用什么?这样的布尔条件?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (...) {
  //  some code
  boolean continueOuterLoop = false;
  for (...) {
    //  some code
    if (...) {
      continueOuterLoop = true;
      break;
    }
    //  more code
  }
  if (continueOuterLoop)
    continue;
  //  more code
}

!将其重构为方法并不能缓解以下任何一种情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
boolean innerLoop (...) {
  for (...) {
    //  some code
    if (...) {
      return true;
    }
    //  more code
  }
  return false;
}

for (...) {
  //  some code
  if (innerLoop(...))
    continue;
  //  more code
}

当然,它有点漂亮,但它仍然绕过多余的布尔值。而且,如果内部循环修改了局部变量,则将其重构为方法并不总是正确的解决方案。

那么,为什么你们都反对标签?请给我一些可靠的理由,以及上述情况的实用替代方法。


如果必须使用大写字母来使用它们,这会引起人们的注意,并避免误认为它们是"类"名称。引起人们的注意还有另一个好处,那就是引起人们的注意,这些人会随之而来并重构您的代码并删除它们。 ;)


惯例是完全避免使用标签。

很少有使用标签来打破循环的正当理由。突破是可以的,但是您可以通过稍微修改设计来消除突破的需要。在您给出的示例中,您将提取"大量代码"部分,并将其放入具有有意义名称的各个方法中。

1
2
3
4
5
6
7
8
9
for ( ;/*stuff*/; )
{
    lotsOfCode();

    if ( !isEnough() )
    {
        moreCode();
    }
}

编辑:看过实际的代码(在这里)后,我认为使用标签可能是使代码可读的最佳方法。在大多数情况下,使用标签是错误的方法,在这种情况下,我认为这很好。


Sun的Java代码风格似乎更喜欢以与变量相同的方式来命名标签,这意味着驼峰大小写,首字母小写。


我最常看到的约定只是驼峰式,例如方法名...

1
myLabel:

但我也看到过带有下划线前缀的标签

1
_myLabel:

或在实验室...

1
labSomething:

但是,从其他答案中,您可能会感觉到您将很难找到一种编码标准,其中规定了"不使用标签"以外的任何内容。那么我想答案是,只要您保持一致,就应该使用对自己有意义的任何样式。


由于标签很少有用,因此似乎没有明确的约定。 Java语言规范中有一个带有标签的示例,它们位于non_cap中。

但是由于它们非常稀有,我认为最好是三思而后行,确定它们是否真的是正确的工具。

如果它们是正确的工具,请将其全部设置为上限,以便其他开发人员(或以后的您自己)立即意识到它们是不寻常的。 (正如克雷格已经指出的那样)


wrt sadie的代码示例:

你给了

1
2
3
4
5
6
7
8
9
10
11
outerloop:
for (...) {
  //  some code
  for (...) {
    //  some code
    if (...)
      continue outerloop;
    //  more code
  }
  //  more code
}

举个例子。你说的对。我最好的猜测是:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void lookMumNoLabels() {
  for (...) {
    // some code
    doMoreInnerCodeLogic(...);
  }
}

private void doMoreInnerCodeLogic(...) {
   for (...) {
      // some code
      if (...) return;
   }
}

但是,在某些示例中,无论采用哪种逻辑,这种重构都无法正确进行。


I know, I should not use labels.

But just assume, I have some code, that could gain a lot in readability from labeled breaks, how do I format them.

莫,你的前提是错的。
问题不应该是"如何格式化它们?"

您的问题应该是"我的代码在循环内包含大量逻辑-如何使其更具可读性?"

这个问题的答案是将代码移动到各个单独的,命名良好的函数中。然后,您根本不需要标记中断。


它们是Java的通用语言-不确定C#是否具有它们。我从未在实践中使用过它们,我想不出避免它们不会导致代码可读性更高的情况。

但是如果您必须-我认为所有上限都可以。大多数人不会使用带标签的中断,因此,当他们看到代码时,上限会跳到他们身上,并迫使他们意识到正在发生的事情。


对流/最佳实践仍将是完全不使用它们并重构代码,以便使用extract作为方法更易读。


推荐阅读