标签是否是 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 的示例中,A
和B
标签都与相同的 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;
}
}
}
Label
loop1
的Statement
是整个loop2 ...
的东西。
如果我们看一下break
的定义,就会发现
中断目标不必是开关、while、do 或 for 语句。
而对于continue
它指出
继续目标必须是 while、do 或 for 语句,否则会发生编译时错误。
这些定义与编译器为continue loop1
语句给出编译器错误并让break loop1
有效保持一致,因为loop2: ...
不是"while、do 或 for 语句"。
关于您的实际问题:标签是不是Java语句?
以下代码是完全合法的,编译得很好
public void method() {
loop:;
}
这是在扩展Statement
->LabeledStatement
->Identifier
:Statement
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
语句:
继续目标必须是
while
、do
或for
语句,否则会发生编译时错误。
很简单,但让我们看一下标记语句的语法(第 14.7 节(。
标签声明:
标识符 : 声明
它可以包含另一个一般的语句,而这些语句又可以是while
、do
或for
("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
语句(中,但没有相应的要求其标签引用特定类型的语句。