14

我一直认为标签只能与循环一起使用,但似乎不是。给出这样的代码:

public class LabelTest {
    public static void main(String[] args) {
        label1: System.out.println("");
        label2: LabelTest t = new LabelTest();  
    }                                               
}

当标记为“label1”的编译行编译但“label2”处的代码给出错误。为什么?为什么我要标记不是“循环”的语句?

4

6 回答 6

18

你会得到一个错误,因为标签不能应用于变量声明,这就是语言语法的定义方式(标签只能在 a 之前Statement,并且 aLocalVariableDeclarationStatement不是 a Statement)。原因可能是它可能会导致对变量范围的混淆。这有效:

    label1: System.out.println("");
    label2: { LabelTest t = new LabelTest(); }
于 2011-02-20T15:40:36.370 回答
7

要添加到 Michael Borgwardt 的答案,您可以为方便起见做这样的事情(前几天我在阅读 Java rt.jar 源代码时发现了这一点):

BlockSegment:
if (conditionIsTrue) {
    doSomeProcessing ();
    if (resultOfProcessingIsFalse()) break BlockSegment;
    otherwiseDoSomeMoreProcessing();
    // These lines get skipped if the break statement
    // above gets executed
}
// This is where you resume execution after the break
anotherStatement();

现在,这在逻辑上等价于:

if (conditionIsTrue) {
    doSomeProcessing ();
    if (!resultOfProcessingIsFalse()) {
        otherwiseDoSomeMoreProcessing();
        // More code here that gets executed
    }
}
anotherStatement();

但是,您可以跳过一些额外的大括号(以及大括号附带的缩进)。也许它看起来更干净(在我看来确实如此),并且在某些地方这种编码风格可能是合适的并且不会令人困惑。

因此,您可以在循环之外使用标签,甚至可以在if语句之外使用标签。例如,这是有效的 Java 语法(也许你可以想出一个理由来做这样的事情):

statementOne();
statementTwo();
BlockLabel: {
    statementThree();
    boolean result = statementFour();
    if (!result) break BlockLabel;
    statementFive();
    statementSix();
}
statementSeven();

如果在break此处执行,则执行跳到标签表示的块的末尾,并被statementFive()跳过statementSix()

if当您在必须跳过的块中有块时 ,这种样式(没有声明)的用处变得更加明显。一般来说,你可以通过足够聪明地使用循环来完成所有事情。但是,在某些情况下,没有循环的标签更容易阅读代码。例如,如果您需要顺序检查参数,您可以这样做或抛出异常。它最终成为代码的清洁度和个人风格的问题。

于 2013-11-05T21:30:06.470 回答
1

它不编译。好问题!我刚刚玩了一点你的代码片段。似乎编译器期望标签后的方法调用或运算符。此时不允许分配。

我认为标签在除 for、while 和 do 之外的运算符之前不被禁止的事实可能是 Java 规范编译器的错误(?!)。无论如何,它不是那么关键。它不会打扰我(个人)。

于 2011-02-20T15:36:18.723 回答
1

Java 语法基于 C 语法。

在 C 语言中,您可以将标签放在任何地方(不仅仅是在循环上),然后用于goto将执行跳转到该行。现在,goto没有在 Java 中实现,但留下了标签,以便它们可以与breakor结合使用continue

这并不重要,因为无论如何这都不是标签的标准用法。使用带有continueor的标签break已经够糟糕了(大多数时候)。随意使用它们也是没有用的。

于 2011-02-20T15:40:03.890 回答
0

我回答这个问题有点晚了。反正,

标签2:标签测试t =新标签测试();-> 不起作用,因为它是一个声明性语句,因为上面的大多数评论都是一样的。要使其工作,只需执行以下操作:

标签2:新标签测试();// 工作正常

于 2021-01-02T15:40:04.217 回答
-2

参考JLS中的标签

于 2011-02-20T15:37:31.283 回答