JavaRush /Java блог /Random /Оператор break в Java
iloveski
37 уровень
Москва

Оператор break в Java

Статья из группы Random
Привет всем коллегам и просто интересующимся.
Оператор break в Java - 1
Сегодня мы рассмотрим такую возможность языка программирования Java, как оператор перехода break. Это первая статья на тему операторов перехода, так что если вам понравится, буду рад написать еще. Сразу хочу заметить, что эта статья рассчитана в первую очередь на начинающих разработчиков, и более продвинутые ученики могут не найти здесь чего-то нового для себя. Итак, поехали. В Java существует 2 способа изменить порядок выполнения инструкций программы: операторы перехода и механизм обработки исключений. К операторам перехода в java относят три оператора: break, continue и return. Сегодня же я предлагаю Вам рассмотреть подробнее оператор break. Механизм обработки исключений является столь обширной темой, что выходит за рамки данной статьи. Есть три способа применения оператора break в java. Первый и самый популярный способ — использование break для досрочного выхода из цикла, например:

public class SimpleExample {
    public static void main(String[] args) {
        findNumberInLoop(3);
    }
    public static void findNumberInLoop(int number){
        for (int i = 0; i < 10; i++) {
            if (i == number) {
                break;
            }
            System.out.println(i);
        }
        System.out.println("cycle was finished");
    }
}
Этот пример выведет на экран:

1
2
cycle was finished
Это означает, что когда счетчик цикла i становится равным переданному параметру number, то есть числу 3, выполнение цикла прерывается досрочно. Если в программе есть несколько вложенных друг в друга циклов, то break выводит только из самого внутреннего цикла, например:

public class SimpleExample {
    public static void main(String[] args) {
        findNumberInLoop(3);
    }
    public static void findNumberInLoop(int number){
        for(int i = 0; i < 5; i++) {
            for (int j =0; j < 10; j++) {
                if(j == number) {
                    break;
                }
                System.out.print(j);
            }
            System.out.println();
        }
        System.out.println("cycles was finished");
    }
}
Этот пример дает вывод:

012
012
012
012
012
cycles was finished
Как видно из примера, внутренний цикл каждый раз прерывается на числе 3 (параметр number), а внешний цикл выполняется 5 раз, как было и задумано. В java можно использовать более одного оператора break внутри цикла, но этого делать не рекомендуется, так как очень сильно ухудшается читабельность и структура кода. Второй способ применения break заключается в использовании его для прерывания выполнения операторов в ветвях switch, например:

public class SimpleExample {
    public static void main(String[] args) {
        square(2);
    }

    public static void square(int number){
        switch (number){
            case 1:
                System.out.println(number*number);
                break;
            case 2:
                System.out.println(number*number);
                break;
            case 3:
                System.out.println(number*number);
                break;
        }
        System.out.println("after switch");
    }
}
Запуск этого примера даст вывод:

4
after switch
Оператор break передал управление коду следующему за всем блоком switch. Если же не указать break в switch в данном примере:

public class SimpleExample {
    public static void main(String[] args) {
        square(2);
    }
    public static void square(int number){
        switch (number){
            case 1:
                System.out.println(number*number);
            case 2:
                System.out.println(number*number);
            case 3:
                System.out.println(number*number);
        }
        System.out.println("after switch");
    }
}
Вывод будет не таким как ожидалось:

4
4
after switch
Это произошло потому, что после выполнения блока case 2 программа продолжила выполнять все следующие за ним блоки case, что и дало нам соответствующий вывод. Иногда такая особенность оператора switch может быть нам выгодна, например:

public class SimpleExample {
    public static void main(String[] args) {
        compare(2);
        compare(7);
        compare(12);
    }
    public static void compare(int number){
        switch (number){
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                System.out.println("number is less than 5 or equal 5");
                break;
            case 6:
            case 7:
            case 8:
            case 9:
                System.out.println("number is greater than 5");
                break;
            default:
                System.out.println("number is less than 0 or greater than 9");
        }
        System.out.println("after switch");
    }
}
Данная программа реализует сравнение заданного числа с числом 5 и дает следующий вывод:

after switch
number is greater than 5
after switch
number is less than 0 or greater than 9
after switch
При первом вызове метода, оператор switch передает управление оператору case 2 и далее до оператора break в case 5. Второй вызов происходит по аналогии с первым, но начинается c case 7. Третий вызов же не находит подходящего значения среди всех case’ов, поэтому выполняется оператор default. Третий способ заключается в использовании оператора break вместо оператора goto из языка C. Для этого мы будем использовать особую форму оператора break, называемую break с меткой. Эта форма выглядит как break метка; Метка - это как правило любое подходящее из пространства имен java имя, предваряющее блок кода. При этом после применения этом блоке кода break с меткой приведет к тому, что код продолжит выполняться с места после блока с соответствующей меткой, например:

public class SimpleExample {
    public static void main(String[] args) {
        howWeUseLabels(true);
        System.out.println();
        howWeUseLabels(false);
    }
    public static void howWeUseLabels(boolean bool) {
        firstBlock:{
            secondBlock:{
                thirdBlock:{
                    System.out.println("We will see it always");
                    if(bool) {
                        break secondBlock;
                    }
                    System.out.println("We won't see it if bool == true");
                }
                System.out.println("We won't see it if bool == true");
            }
            System.out.println("We will see it always");
        }
    }
}
Этот пример даст следующий вывод:

We will see it always
We will see it always

We will see it always
We won't see it if bool == true
We won't see it if bool == true
We will see it always
После первого вызова метода, оператор break осуществляет передачу управления в конец блока secondBlock, выходя из secondBlock и thirdBlock, при этом выполняя еще один оператор println(), в конце firstBlock. После второго вызова на экран выводится все строки. Метки можно использовать также для обозначения циклов. При этом следует помнить, что переходить к метке можно только изнутри блока кода, обозначенного меткой, например такой код не скомпилируется:

public class SimpleExample {
    public static void main(String[] args) {
        label:{
            System.out.println("inside label");
        }
        if(true) {
            break label;
        }
        System.out.println("This is error");
    }
}
Замечания насчет чистоты кода и оператора break: Существует общепризнанный совет использовать оператор break очень осторожно, так как применение break усложняет понимание цикла и заставляет программиста заглянуть внутрь цикла, чтобы разобраться в нюансах его работы. Есть эвристического правило, что использовать break можно увереннее в более коротких циклах и с большей осторожностью в длинных и имеющих глубокую вложенность, так как это увеличивает вероятность ошибки и усложняет чтение и понимание вашего кода другими программистами. Как я уже писал выше, использование большого количества break, разбросанных по всему коду, говорит о том, что программист не до конца понимает, почему он написал свой код именно так. Возможно, стоит рассмотреть рефакторинг такого цикла, путем разбиения на несколько более маленьких циклов. Старайтесь с осторожностью использовать break с меткой в качестве замены goto, так как это усложняет структуру кода. Вот и все, что я хотел сегодня рассказать об операторе break в java. Буду рад конструктивной критике, а также готов написать продолжение про операторы continue и return, если Вам это интересно.
Комментарии (8)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Roman Grand Уровень 35
6 марта 2021
В статье много ошибок в примерах вывода, поэтому сложно воспринимать "правильную" работу оператора без проверки в компиляторе. И поэтому, будьте осторожны в изучении конкретно этой статьи! UPD: данные, представленные в статье помогли на практике при решении задачи)
Алексей Уровень 22
30 сентября 2020
в самом первом примере на экран выведется 0 //т.к. i = 0 первоначально 1 2 cycle was finished
Murad Уровень 14
7 января 2020
Спасибо за инфу, если не ошибаюсь подобное применяется преимущественно в процедурном(функциональном программировании), наверное это C. Учитывая гибкость самого языка java наверное метки уже уйдут в прошлое, очень очень редко может пригодиться, но мне кажется гораздо важнее построить(спроектировать) правильно сам алгоритм и потом реализовывать, в первом случае как раз метки и не пригодятся, во втором могут пригодится если изначально в алгоритме есть просчеты
iOSif_StyleIN Уровень 26
16 мая 2018
Спасибо что пересказал текст из книги типа Шилдта или Хортсманна, но вариант с меткой очень не рекомендуется! позже ссылку найду. Это мне один джаварашовец сказал, когда я не понимал почему мой код с меткой в задаче не сработал. Увы, но это так