использование меток в Java без "петель" - PullRequest
14 голосов
/ 20 февраля 2011

Я всегда думал, что метки должны использоваться только с петлями, но, похоже, нет.Предоставление такого кода:

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

Когда скомпилированная строка с меткой «label1» компилируется, но код в «label2» выдает ошибки.Почему это?И почему я хотел бы маркировать операторы, которые не являются "петлями"?

Ответы [ 5 ]

18 голосов
/ 20 февраля 2011

Вы получаете ошибку, потому что метка не может быть применена к объявлениям переменных, просто так определяется грамматика языка (метка может предшествовать только Statement, а LocalVariableDeclarationStatement не является Statement). Причина, вероятно, в том, что это может привести к путанице в отношении переменной области. Это работает:

    label1: System.out.println("");
    label2: { LabelTest t = new LabelTest(); }
7 голосов
/ 06 ноября 2013

Чтобы добавить ответ Михаэля Боргвардта, для удобства вы можете сделать что-то подобное (я обнаружил это на днях, читая исходный код 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) становится более очевидной, когда у вас есть блоки внутри блоков, где вы должны пропустить. В общем, вы можете добиться всего с достаточно умным использованием циклов. Тем не менее, есть несколько случаев, когда метки без циклов облегчают чтение кода. Например, если вам нужно последовательно проверять параметры, вы можете сделать это или вызвать исключение. В конечном итоге это вопрос чистоты кода и личного стиля.

1 голос
/ 20 февраля 2011

Синтаксис Java основан на синтаксисе языка C.

В C вы можете поместить метку в любом месте (не только в циклах), а затем использовать goto, чтобы перейти к выполнению этой строки.Теперь goto не был реализован в Java, но метки были оставлены, чтобы их можно было использовать в сочетании с break или continue.

Это не так важно, так как в любом случае это не стандартное использование ярлыков.Использование меток с continue или break достаточно плохо (в большинстве случаев).Свободное их использование также бесполезно.

1 голос
/ 20 февраля 2011

Не компилируется. Хороший вопрос! Я только что немного поиграл с твоим фрагментом кода. Похоже, что компилятор ожидает вызова метода или оператора после метки. Это не позволяет назначение на этом этапе.

Я думаю, что тот факт, что label не запрещен перед операторами, отличными от for, while и do, вероятно, является ошибкой (?!) Компилятора спецификации Java. Во всяком случае, это не так критично. Меня это не беспокоит (лично).

0 голосов
/ 20 февраля 2011

См. Lable в JLS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...