1

有人可以告诉我为什么编译器说以下代码中缺少标签:

情况1:

错误:标签丢失

void crazyLoop() {
    int c = 0;
    JACK: while (c < 8) {
        JILL: System.out.println(c);
        if (c > 3)
            break JILL;
        else
            c++;
    }
}

JILL是可以到达的,因为我已经声明为JILLinsideJACK而不是 outside JACK

案例2:

错误: c 无法解析。如果我这样做:

void crazyLoop() {
    JILL:int c = 0;
    JACK: while (c < 8) {
         System.out.println(c);
        if (c > 3)
            break JILL;
        else
            c++;
    }
}

编译器说c无法解析为变量。

有人可以解释发生了什么吗?

4

3 回答 3

1

从 JSL 14.15 开始。休息声明

带有标签标识符的 break 语句尝试将控制权转移到具有与其标签相同标识符的封闭标签语句(第 14.7 节)

所以这个错误是由没有引用循环标签的break语句引起的。此外,只有语句可以有标签前缀。见文档

以下代码编译成功:

 void crazyLoop() {
    int c = 0;
    ILL:
    c= 0;

JACK: while (c < 8) {
     System.out.println(c);
    if (c > 3)
        break JACK;
    else
        c++;
}
于 2016-11-10T13:46:32.787 回答
1

问题在于JILL:int c = 0;,因为根据 Java 语法它是无效的。因此,错误c 无法解析为变量只是第一个错误的影响。

您不能在局部变量声明之前使用标签。有关更多详细信息,请参阅此答案

于 2016-11-10T13:44:26.037 回答
0

请参阅java 参考

带标签语句的标签范围是立即包含的Statement

这意味着最好将标签放在复合语句(如 for 循环等)之前。

JACK: while (c < 8) {
    JILL: System.out.println(c);
    if (c > 3)
        break JILL;
    else
        c++;
}

JILL 的范围只是System.out.println(c);. break JACK会跳出while循环。在声明之后 JILL 是未知的。

未知的第二个错误c似乎编译器将标记的语句封装在{ }. 这可能是一个编译器“错误”(复合语句假设) - 但也许其他读者可以有所启发:尝试其他编译器,在声明的参考中找到一些东西。

于 2016-11-10T13:41:47.397 回答