Подтвердить что ты не робот

Использование ярлыков в java без "петель"

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

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

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

4b9b3361

Ответ 1

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

    label1: System.out.println("");
    label2: { LabelTest t = new LabelTest(); }

Ответ 2

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

Ответ 3

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

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

Ответ 4

Синтаксис Java основан на синтаксисе Си.

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

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

Ответ 5

Обратитесь к Lable в JLS