Пожалуйста, объясните использование помеченных заявлений - PullRequest
8 голосов
/ 26 апреля 2010
  • Разрывает и продолжает ли использование Java только помеченные операторы?
  • Когда вы использовали помеченные заявления в своих программах?

Извините, фрагмент кода был удален. Я делю вопрос

Ответы [ 3 ]

17 голосов
/ 26 апреля 2010

JLS 14.7 Помеченные операторы

(отредактировано для ясности)

Заявления могут иметь префиксы меток ( Идентификатор : Оператор ). Идентификатор объявляется как метка непосредственно содержащегося Заявления .

В отличие от C и C ++, язык программирования Java не имеет оператора goto; метки операторов идентификатора используются с операторами break ( §14.15 ) или continue ( §14.16 ), появляющимися в любом месте внутри оператора с метками.

Таким образом, JLS ясно, что метки используются с break или continue, и никакой другой грамматический элемент языка программирования Java не использует его.

Строго говоря, break и continue, помечены или нет, НИКОГДА не требуется. Они всегда могут быть написаны из кода. Однако использование идиоматически может привести к более читаемому коду.


Вот иллюстративный пример: учитывая int[], мы хотим:

  • печать "One (1)" на 1
  • печать "Two (2)" на 2
  • печать "Zero " на 0
  • немедленно прекратить обработку на любом другом номере

    int[] arr = { 1, 2, 0, 1, -1, 0, 2 };
    loop:
    for (int num : arr) {
        switch (num) {
        case 1:
            System.out.print("One ");
            break;
        case 2:
            System.out.print("Two ");
            break;
        case 0:
            System.out.print("Zero ");
            continue loop;
        default:
            break loop;
        }
        System.out.print("(" + num + ") ");
    }
    // prints "One (1) Two (2) Zero One (1) "
    

Здесь мы видим, что:

  • Различные числа обрабатываются в switch
  • Немеченый break в switch используется, чтобы избежать «провала» между делами
  • Метка continue loop; используется для пропуска последующей обработки на case 0: (метка здесь не нужна)
  • с меткой break loop; используется для завершения цикла на default: (метка здесь необходима; в противном случае это switch break)

С маркировкой break / continue также можно использовать вне вложенных циклов; его можно использовать, когда switch вложено в цикл. В более общем смысле, он используется, когда существует потенциально многократная цель break / continue, и вы хотите выбрать ту, которая не сразу включает оператор break / continue.


Вот еще один пример:

    morningRoutine: {
        phase1: eatBreakfast();
        if (grumpy) break morningRoutine;
        phase2: kissWife();
        phase3: hugChildren();
    }
    http://stackoverflow.com is the best website ever!

Вот еще один случай использования помеченного break не внутри итеративного оператора, а внутри простого блока. Можно утверждать, что метки приводят к лучшей читаемости; этот момент субъективен.

И нет, последняя строка НЕ ​​дает ошибку времени компиляции. Это на самом деле вдохновлено Java Puzzlers Puzzle 22: Dupe of URL. К сожалению, загадка не дает более «правильного» использования помеченных выражений.

6 голосов
/ 26 апреля 2010

Да, break и continue - единственные два использования для помеченных операторов в Java. (У Java нет оператора goto.)

Вы можете использовать метку, чтобы вырваться из вложенных циклов.

outer:
    for (int i = 0; i < 5; i++) {    
        for (int j = 0; j < 5; j++) {
            System.out.println("Hello");
            continue outer;
        } // end of inner loop
        System.out.println("outer"); // Never prints
    }
System.out.println("Good-Bye");

Когда вы continue возвращаетесь к метке outer, вы пропускаете остаток как внутреннего, так и внешнего цикла, включая оператор print.

3 голосов
/ 26 апреля 2010
search:
    for (i = 0; i < arrayOfInts.length; i++) {
        for (j = 0; j < arrayOfInts[i].length; j++) {
            if (arrayOfInts[i][j] == searchfor) {
                foundIt = true;
                break search;
            }
        }
    }
...