Опубликован: 11.12.2003 | Доступ: свободный | Студентов: 43882 / 3317 | Оценка: 4.28 / 3.68 | Длительность: 30:42:00
ISBN: 978-5-9556-0006-2
Специальности: Системный архитектор
Лекция 10:

Операторы и структура кода. Исключения

< Лекция 9 || Лекция 10: 123456 || Лекция 11 >

Операторы break и continue

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

Оператор continue

Оператор continue может использоваться в циклах while, do, for. Если в потоке вычислений встречается оператор continue, то выполнение текущей последовательности операторов (выражений) должно быть прекращено и управление будет передано на начало блока, содержащего этот оператор.

...
int x = (int)(Math.random()*10);
int arr[]  = {....}
for(int cnt=0;cnt<10;cnt++) {
   if(arr[cnt] == x) continue;
   ...
}

В данном случае, если в массиве arr встретится значение, равное x, то выполнится оператор continue и все операторы до конца блока будут пропущены, а управление будет передано на начало цикла.

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

Рассмотрим пример:

public class Test {
   public Test() {
   }
   public static void main(String[] args) {
      Test t = new Test();
      for(int i=0; i < 10; i++){
         if(i % 2 == 0) continue;
         System.out.print(" i=" + i);
      } 
   }
}

В результате работы на консоль будет выведено:

i=1 i=3 i=5 i=7 i=9

При выполнении условия в строке 7 нормальная последовательность выполнения операторов будет прервана и управление будет передано на начало цикла. Таким образом, на консоль будут выводиться только нечетные значения.

Оператор break

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

public class Test {
  public Test() {
  }
  public static void main(String[] args) {
    Test t = new Test();
    int [] x = {1,2,4,0,8};
    int y  = 8;
    for(int cnt=0;cnt < x.length;cnt++) {
      if(0 == x[cnt]) break;
      System.out.println("y/x = " + y/x[cnt]);
    }
  }
}

На консоль будет выведено:

y/x = 8
y/x = 4
y/x = 2

При этом ошибки, связанной с делением на ноль, не произойдет, т.к. если значение элемента массива будет равно 0, то будет выполнено условие в строке 9 и выполнение цикла for будет прервано.

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

Именованные блоки

В реальной практике достаточно часто используются вложенные циклы. Соответственно, может возникнуть ситуация, когда из вложенного цикла нужно прервать внешний. Простое использование break или continue не решает этой задачи, однако в Java можно именовать блок кода и явно указать операторам, к какому из них относится выполняемое действие. Делается это путем присвоения метки операторам do, while, for.

Метка - это любая допустимая в данном контексте лексема, оканчивающаяся двоеточием.

Рассмотрим следующий пример:

...
int array[][] = {...};
for(int i=0;i<5;i++) {
   for(j=0;j<4; j++) {
      ...
      if(array[i][j] == caseValue) break;
      ...
   }
}
...

В данном случае при выполнении условия будет прервано выполнение цикла по j, цикл по i продолжится со следующего значения. Для того, чтобы прервать выполнение обоих циклов, используется метка:

...
int array[][] = {:..};
outerLoop: for(int i=0;i<5;i++) {
   for(j=0;j<4; j++){
      ...
      if(array[i][j] == caseValue) 
	     break outerLoop;
      ...
   }
}
...

Оператор break также может использоваться с именованными блоками.

Между операторами break и continue есть еще одно существенное отличие. Оператор break может использоваться с любым именованным блоком, в этом случае его действие в чем-то похоже на действие goto. Оператор continue (как и отмечалось ранее) может быть использован только в теле цикла. То есть такая конструкция будет вполне приемлемой:

lbl:{
   ...
   if( val > maxVal) break lbl;
   ...
}

В то время как оператор continue здесь применять нельзя. В данном случае при выполнении условия if выполнение блока с меткой lbl будет прервано, то есть управление будет передано на оператор (выражение), следующий непосредственно за закрывающей фигурной скобкой.

Метки используют пространство имен, отличное от пространства имен классов и методов.

Так, следующий пример кода будет вполне работоспособным:

public class Test {
   public Test() {
   }
   public static void main(String[] args) {
      Test t = new Test();
      t.test();
   }
   void test() {
      Test: {
         test: for(int i =0;true;i++) {
            if(i % 2 == 0) continue test;
            if(i > 10) break Test;
            System.out.print(i + " ");
         }
      }
   }
}

Для составления меток применяются те же синтаксические правила, что и для переменных, за тем исключением, что метки всегда оканчиваются двоеточием. Метки всегда должны быть привязаны к какому-либо блоку кода. Допускается использование меток с одинаковыми именами, но нельзя применять одинаковые имена в пределах видимости блока. Т.е. такая конструкция допустима:

lbl: {
   ...
   System.out.println("Block 1");
   ...
}
...
lbl: {
   ...
   System.out.println("Block 2");
   ...
}

А такая нет:

lbl: {
   ...
   lbl: {
      ...
   }
   ...
}

Оператор return

Этот оператор предназначен для возврата управления из вызываемого метода в вызывающий. Если в последовательности операторов выполняется return, то управление немедленно (если это не оговорено особо) передается в вызывающий метод. Оператор return может иметь, а может и не иметь аргументов. Если метод не возвращает значений (объявлен как void ), то в этом и только этом случае выражение return применяется без аргументов. Если возвращаемое значение есть, то return обязательно должен применяться с аргументом, чье значение и будет возвращено.

В качестве аргумента return может использоваться выражение

return (x*y +10) /11;

В этом случае сначала будет выполнено выражение, а затем результат его выполнения будет передан в вызывающий метод. Если выражение будет завершено ненормально, то и оператор return будет завершен ненормально. Например, если во время выполнения выражения в операторе return возникнет исключение, то никакого значения метод не вернет, будет обрабатываться ошибка.

В методе может быть более одного оператора return.

Оператор synchronized

Этот оператор применяется для исключения взаимного влияния нескольких потоков при выполнении кода, он будет подробно рассмотрен в лекции 12, посвященной потокам исполнения.

< Лекция 9 || Лекция 10: 123456 || Лекция 11 >
Георгий Кузнецов
Георгий Кузнецов

1. По истечению срока курса, будет ли доступ к курсу закрыт? (в данном случае написано 29 января)

2. Так и не понял: что такое конструктор?

Вячеслав Лопачёв
Вячеслав Лопачёв

Хочу заново пройти курс. Можно ли как-то сбросить прогресс и обновить сертификат?

Мария Самосудова
Мария Самосудова
Россия, Калининградская область
Анна Фадеева
Анна Фадеева
Россия, Набережные Челны, КФУ