标签是不是 Java 语句?



标签是否是 Java 语句,如果标签是语句,它在 Java 语言规范中在哪里定义为语句?

我的问题与Jan Lahoda在我发送给Oracle的错误报告中的以下回复有关。我无法在那里讨论它,因为我无法在OpenJDK Jira中获得帐户。

https://bugs.openjdk.java.net/browse/JDK-8211052

例如,在以下情况下:A: B: while (true) continue A;应用"继续"的语句不是"while (true) continue A;",而是"B: while (true) continue A;",并且规范要求继续的目标是 while/do/for 语句,这里没有实现。因此编译时错误。

我认为 Java 中的标签不是语句,在 Jan 的示例中,AB标签都与相同的 while-loop 语句相关,然后不应触发编译时错误。

加法:

Java 中标记的 while/do/for 语句不是 while/do/for 语句吗?

遵循 JLS 后,Statement可以是

StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement

LabeledStatement存在

Identifier : Statement

并声明

标识符被声明为立即包含的语句的标签

所以在像这样的循环的情况下

public void method() {
loop1: loop2: while (true) {
if (true) {
break loop1;
} else {
continue loop1;
}
}
}

Labelloop1Statement是整个loop2 ...的东西。

如果我们看一下break的定义,就会发现

中断目标不必是开关、while、do 或 for 语句。

而对于continue它指出

继续目标必须是 while、do 或 for 语句,否则会发生编译时错误。

这些定义与编译器为continue loop1语句给出编译器错误并让break loop1有效保持一致,因为loop2: ...不是"while、do 或 for 语句"。


关于您的实际问题:标签是不是Java语句?

以下代码是完全合法的,编译得很好

public void method() {
loop:;
}

这是在扩展Statement->LabeledStatement->IdentifierStatement

-> 循环 :Statement-> 循环 :StatementWithoutTrailingSubstatement-> 循环 :EmptyStatement->
loop : ;

不,标签本身不是语句,标识符(然后称为"标签"(加上列加EmptyStatement(;(是。


在 Java 中标记为 while/do/for 语句不是 while/do/for 语句吗?

不!

LabeledStatement就是这样:LabeledStatement.标记的 while 是Statement -> Label -> Identifier : Statement -> Identifier : WhileStatement这与Statement -> WhileStatement根本不同!

JLS 第 14.16 节讨论了continue语句:

继续目标必须是whiledofor语句,否则会发生编译时错误。

很简单,但让我们看一下标记语句的语法(第 14.7 节(。

标签声明:

标识符 : 声明

它可以包含另一个一般的语句,而这些语句又可以是whiledofor("wdf"(语句,也可以包含另一个标记语句(第 14.5 节((或其他类型的语句(。

但标签本身不是一个陈述;它需要另一个陈述作为它的一部分。

接下来,允许嵌套标记语句,因此通常您可以执行以下操作:

A: B: yourStatementHere;

如果需要,可以进一步嵌套它:

A: B: C: D: E: F: G: yourStatementHere;

但是,随着

A: B: while (true) continue A;

A:标记的语句是另一个标记语句,而不是"wdf"语句,即使B:标记语句本身包含while语句也是如此。

如果你戴上律师帽,你可以争辩说,上面关于continue语句需要引用"wdf"语句的句子没有说明"wdf"语句嵌套在标记语句中,所以它应该是一个编译器错误。

这对我来说似乎很挑剔;也许JLS应该有一个子句,指示"wdf"语句本身可以嵌套在标记的语句中。

但在这种情况发生之前,这似乎是上面引用的JLS提供的措辞的正确结果,如果不是有意的结果。

那么为什么允许break这样做呢?

A: B: while (true) break A;  // no error

JLS 的第 14.15 节中没有相应的行,其中讨论了break语句,强制break语句的目标必须是"wdf"语句。break语句必须仍位于"wdf"语句(或switch语句(中,但没有相应的要求其标签引用特定类型的语句。

最新更新