Метка - это оператор Java или нет? - PullRequest
0 голосов
/ 24 сентября 2018

Является ли метка оператором Java или нет, и если метка является инструкцией, где она определена как инструкция в спецификации языка Java?

Мой вопрос касается следующего ответа Яна Лаходы в сообщении об ошибкеотчет, который я отправил в Oracle.Я не могу обсудить это там, потому что не могу получить учетную запись в OpenJDK Jira.

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

В случае, например: A: B: while (true) continue A; заявление ото, что применяется "continue", это не "while (true) continue A;", а "B: while (true) continue A;", и спецификация требует, чтобы целью для продолжения был оператор while / do / for, который здесь не выполняется.Следовательно, ошибка времени компиляции.

Я думаю, что метка в Java не является оператором, и в примере Яна метки A и B относятся к одному и тому же оператору while итогда никакая ошибка времени компиляции не должна вызываться.

Добавление:

Не является ли помеченным while / do / for в Java некоторое время/ делать / для заявления?

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

После JLS a Statement может быть

StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement

с LabeledStatement, равным

Identifier : Statement

и указанным

Идентификатор объявляется как метка непосредственно содержащегося оператора

, поэтому в случае цикла, подобного

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

Statement из Label loop1 - это все loop2 ... вещи.

И если мы посмотрим на определение break, то будет указано, что

целью прерывания не обязательно должен быть переключатель, в то время как, do или для оператора.

, тогда как для continue указывается

Целью продолжения должно быть while, do, или для оператора, или для компиляцииошибка времени.

Эти определения правильно соответствуют компилятору, выдающему ошибку компилятора для оператора continue loop1 и позволяющей break loop1 быть действительным, поскольку loop2: ... равно , а не a "while, do или for Statement" .


Относительно вашего фактического вопроса: Является ли label выражением Java или нет?

Следующий код совершенно допустим и прекрасно компилируется

public void method() {
    loop:;
}

Это следует за расширением цикла Statement -> LabeledStatement -> Identifier: Statement ->: Statement-> loop: StatementWithoutTrailingSubstatement -> loop: EmptyStatement ->

loop : ;

Нет, метка сама по себе не является выражением, идентификатором (который затем называется «метка») плюс знак плюсEmptyStatement (;) однако.


Не помечен как оператор / do / for в Java как оператор while / do / for?

Нет!
A LabeledStatement это именно то, что: a LabeledStatement.В то время как Statement -> Label -> Identifier : Statement -> Identifier : WhileStatement помечено как нечто принципиально отличное от Statement -> WhileStatement!

0 голосов
/ 24 сентября 2018

JLS , раздел 14.16 , говорит о выражении continue:

Цель продолжения должна быть while, do или forили во время компиляции.

Достаточно просто, но давайте посмотрим на грамматику для помеченного оператора ( Раздел 14.7 ).

LabeledStatement:

Идентификатор: оператор

Он может содержать другие операторы в целом, которые, в свою очередь, могут быть 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: помеченное заявление содержит a while заявление.

Если вы наденете свою адвокатскую шляпу, вы можете утверждать, что приведенное выше предложение о continue оператор, который должен ссылаться на оператор "wdf", ничего не говорит о том, что оператор "wdf" вложен в помеченный оператор, поэтому это должна быть ошибка компилятора.

Это кажется мне очень разборчивым;возможно, в JLS должен был быть пункт, указывающий, что выражение «wdf» может быть само вложено в помеченный оператор.

Но до тех пор, пока это не произойдет, это будет правильным, хотя и непреднамеренным, следствием формулировкиJLS предоставляет, как указано выше.

Так почему break разрешено делать это?

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

В разделе 14.15 JLS нет соответствующей строки,который говорит об операторе break, который обеспечивает, что целью оператора break должен быть оператор "wdf".Оператор break должен по-прежнему находиться внутри оператора "wdf" (или оператора switch), но нет соответствующего требования, чтобы его метка ссылалась на оператор определенного типа.

...