JavaRush /Java Blog /Random EN /Jump statements in Java

Jump statements in Java

Published in the Random EN group
Hello! Today we will talk about jump operators in the Java language:
  • return
  • break
  • continue
  • goto
To begin with, let's define what it is in general. As you know, in a normal situation, the program is executed linearly - from top to bottom, command by command. The linear course of the program can be changed by the so-called control structures: for example, branches ( if) and loops ( for, whileetc.). In addition to control structures, jump statements can change the linear execution of a program. They are responsible for redirecting program execution to a specific location, which depends on the context and the specific statement. Jump statements in Java - 1Let's take a closer look at each of the four operators.

return

It is with this operator that beginners most often first of all get acquainted. The statement returnterminates the method in which it was called, and program execution returns to where the method was called from. I returnhave two forms:
  1. Ends method execution immediately.
  2. Immediately ends the execution of the method and returns some value as the result of the method.
The syntax for both forms is:
return;
return value; // где value — некоторое возвращаемое meaning
Methods that return some value must have at least one operator returnwith a return value that is guaranteed to be called, and an operator returnwithout a return value is not allowed. Consider the examples below:
public int sum(int a, int b) {
    return a + b;
}

public String getGreetings(String name) {
    return "Hello " + name;
}

public int max(int x, int y) {
    if (x > y) {
        return x;
    } else {
        return y;
    }
}
Methods that do not return values ​​(methods void) are allowed, but not required, to have at least one statement returnwithout a return value, and not allowed to have any statement returnwith a return value. Let's look at the examples below:
public void print(String s) {
    // наличие return в void методах не обязательно
    System.out.println(s);
}

//Метод выведет в консоль число, если оно нечетное
public void printIfOdd(int number) {
    if (number % 2 == 0) {
        // Если число четное, метод завершит свою работу
        // Наличие return в void методах опционально
        return;
    }

    System.out.println(number);
}

// Метод выведет в консоль наибольшее meaning из массива
private void printMaxInArray(int[] array) {
    if (array == null || array.length == 0) {
        /*
         Если массив пуст, метод завершит свою работу.
         Иногда полезно проверять подобным образом аргументы метода вначале и прерывать выполнение метода, если аргументы не подходят для дальнейшей корректной работы
        */
        System.out.println("Empty array");
        return;
    }

    int max = array[1];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max) {
            max = array[i];
        }
    }
    System.out.println(max);
}

labels

Before looking at the breakand operators continue, I would like to talk about labels in the Java language. This is important because in some situations the breakand operators continueare used in conjunction with labels. But first, try to answer the question of whether this code will compile:
public static void main(String[] args) {
    https://www.google.com/
    System.out.println("Interesting...");
}
A label is a named piece of code. By itself, the label does not carry any functionality. This is something like a bookmark in the code that the programmer intends to use later. The label in the code is defined very simply - through the name and the colon. For example:
  • labelName:
  • outerLoop:
  • printing:
  • anyWordYouLike:
And this is what the labels look like inside the Java code:
public static void main(String[] args) {
    definePrintName:
    System.out.println("Таблица Умножения");

    loop1:
    for (int i = 1; i <= 10; i++) {
        loop2:
        for (int j = 1; j <= 10; j++) {
            System.out.printf("%4d", i * j);
        }
        System.out.println();
    }
}
The output of the method mainwill be as follows:
Таблица Умножения
   1   2   3   4   5   6   7   8   9   10
   2   4   6   8   10  12  14  16  18  20
   3   6   9   12  15  18  21  24  27  30
   4   8   12  16  20  24  28  32  36  40
   5   10  15  20  25  30  35  40  45  50
   6   12  18  24  30  36  42  48  54  60
   7   14  21  28  35  42  49  56  63  70
   8   16  24  32  40  48  56  64  72  80
   9   18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90  100

Process finished with exit code 0
In the example above definePrintName, , loop1:and loop2:are labels. loop1:and loop2:"mark" two cycles - external and internal. We will cover the use of labels in the section below. In the meantime, if you answered “no” to the question of whether this code will compile:
public static void main(String[] args) {
      https://www.google.com/
      System.out.println("Interesting...");
  }
Try answering it again using the IDE.

break

The operator breakis used in two cases:
  1. To end any execution branch in a switch-case block.
  2. To interrupt a loop.
The operator has two forms: with marking (label) and without. The syntax for both forms is:
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
In switch-case blocks, the statement breakis used without labels:
public static void main(String[] args) {
    int dayOfWeekInt = 4;
    String dayOfWeek;
    switch (dayOfWeekInt) {
        case 1:
            dayOfWeek = "Monday";
            break;
        case 2:
            dayOfWeek = "Tuesday";
            break;
        case 3:
            dayOfWeek = "Wednesday";
            break;
        case 4:
            dayOfWeek = "Thursday";
            break;
        case 5:
            dayOfWeek = "Friday";
            break;
        case 6:
            dayOfWeek = "Saturday";
            break;
        case 7:
            dayOfWeek = "Sunday";
            break;
        default:
            dayOfWeek = "Неизвестный день";
            break;
    }

    System.out.println("Сегодня " + dayOfWeek);
}
In loops, a statement breakis used to abort further iterations after certain conditions are met. Often this can be seen when you need to iterate through an array or collection of elements and find some element in it that satisfies the desired conditions. Let's consider such an example. We have an array and we need to determine if the array contains negative elements:
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;

for (int i = 0; i < a.length; i++) {
   if (a[i] < 0) {
       /*
        Как только найдется
        хотя бы один отрицательный элемент,
        мы прервем цикл с помощью
        оператора break, потому что
        мы выяснor то, что нас интересовало,
        и дальнейший перебор элементов не имеет смысла.
        */
       arrayHasNegativeElements = true;
       break;
   }
}
Consider the same example with different loops. Cycle for-each:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    for (int number : a) {
        if (number < 0) {
            arrayHasNegativeElements = true;
            break;
        }
    }
}
Cycle while:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    int counter = 0;
    while (counter < a.length) {
        if (a[counter] < 0) {
            arrayHasNegativeElements = true;
            break;
        }
        counter ++;
    }
}
Cycle do-while:
public static void main(String[] args) {
    int a[] = {1,2,234,-123,12,-2,312,0,412,433};
    boolean arrayHasNegativeElements = false;

    int counter = 0;
    do {
        if (a[counter] < 0) {
            arrayHasNegativeElements = true;
            break;
        }
        counter ++;
    } while (counter < a.length);
}
Another example of a statement breakin loops is to break an infinite loop when certain conditions are met. Here is an example of a program that displays the string that the user entered until the user enters the word “stop”:
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String line;

    while (true) {
        line = scanner.nextLine();
        if ("stop".equals(line)){
            /*
             Прерываем бесконечный цикл,
             при достижении
             определенного условия
             */
            break;
        }
        System.out.println("Пользователь ввел: " + line);
    }
}
Consider using an operator breakin conjunction with a label. A cue interrupt is used in cases where multiple loops are nested within each other. In this case, one of the cycles (or all cycles) is marked with a label. Further, the operator, breaktogether with the indication of the label, interrupts the desired cycle. Consider an example in which we need to understand if there is a negative element, but not in an array, but in a matrix:
public static void main(String[] args) {
   int[][] a = {
           {1, 2, 3},
           {-412, 12, 0},
           {1223, 474, -54}
   };

   boolean hasNegative = false;

   searchNegative:
       for (int i = 0; i < a.length; i++) {
           for (int j = 0; j < a[i].length; j++) {
               if (a[i][j] < 0) {
                   /*
                       Если использовать break без метки,
                       тогда прервется вложенный цикл for,
                       но внешний продолжит выполнять свои итерации
                       и поиск продолжится.

                       Поэтому мы "помечаем" внешний цикл меткой `searchNegative`
                       и прерываем внешний цикл оператором break совместно с нужной меткой.
                    */
                   hasNegative = true;
                   break searchNegative;
               }
           }
       }
}

continuous

The operator continuealso has two forms - with and without a label:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
Unlike the statement break, which aborts all remaining iterations of the loop, the statement continueaborts the current iteration and causes the next iteration to start. Jump statements in Java - 2This can be useful if you need to perform some operations on elements that satisfy certain conditions. Let's say we have a string and we want to count the number of words that start with the letter "m":
public static void main(String[] args) {
    String sentence = "Мама мыла раму";
    String[] words = sentence.split(" ");

    int mWordsCount = 0;

    for (int i = 0; i < words.length; i++) {
        if ( ! words[i].toLowerCase().startsWith("м")) {
            /*
             Если слово не начинается с буквы м,
             то текущая итерация прервется и цикл
             ПРОДОЛЖИТ выполнение со следующей итерации
             */
            continue;
        }

        mWordsCount ++;
    }

    System.out.println("Кол-во слов, начинающихся с буквы М в предложении: " + "[" + sentence + "] = " + mWordsCount);
}
After executing this code, you will see the following output in the console:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
The operator, continuetogether with the label, is also used when iterating over elements. Imagine a matrix in which we need to count the number of rows with negative elements:
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    rowsLoop:
    // Проходим по каждой строке
        for (int[] arr : a) {
            for (int number : arr) {
                if (number < 0) {
                    /*
                     Если в текущей строке найдется
                     хотя бы 1 отрицательный элемент,
                     тогда мы увеличим переменную счетчик,
                     и с помощью оператора continue rowsLoop
                     прервем текущую итерацию внешнего цикла и
                     принудительно начнем следующую
                     */
                    rowsWithNegativeElementsCount ++;
                    continue rowsLoop;
                }
            }
        }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
The output of this code will be:
Rows With Negative Elements Count = 3
It's worth saying that the break, continueand operators returncan be used in different ways to achieve the same functionality. So, you can rewrite the last example and continueuse instead break:
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    for (int[] arr : a) {
        for (int number : arr) {
            if (number < 0) {
                rowsWithNegativeElementsCount ++;
                break;
            }
        }
    }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
The difference between breakand continuewith a label is what breakterminates the iterations of the loop in which it is written. And continuewith a label skips the current iteration of the cycle marked with a label. In some situations, you can replace one with another, and everything will remain the same in the functionality of the program. We will talk about what is better to choose (spoiler: code readability) a little lower. The operator breakcan be replaced not only by continuewith a label, but also by return. Just before that, you need to move the nested loop into a separate method:
public static void main(String[] args) {
    int[][] a = {
            {1, 23, -1, 23, -12},
            {21, 21, 0, 23, 123, 45},
            {123, 3},
            {123, -5, 4, -3},
            {-1, -2, -3}
    };

    int rowsWithNegativeElementsCount = 0;

    for (int[] arr : a) {
        if (arrayHasNegativeElements(arr)) {
            rowsWithNegativeElementsCount ++;
        }
    }

    System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}

static boolean arrayHasNegativeElements(int[] array) {
    for (int number : array) {
        if (number < 0) {
            return true;
        }
    }

    return false;
}
Lots of ways to write the same thing. Which one to choose? In industrial programming, this issue is decided by the ease of perception of the code. The simpler it is written, the better. The more nested loops, the harder it is to read the code. Especially if the loops are marked with different labels that are used in interrupts and continuations ( breakand continue). If it is possible not to use tags, it is better to do so. Otherwise, try to write as clearly and beautifully as possible.

goto

Some programming languages ​​have the goto. It usually redirects code execution to some part of the program marked with the label. But in Java goto, you can say both are and are not. Let's figure it out. The list of keywords in Java includes the word goto. However, this operator is marked as not used. The fact is that James Gosling, the creator of the Java language, initially laid in the JVM support for the goto. However, later this feature was cut out. One of the reasons is that blocks of code containing the operator gotodidn't read as well as blocks of code that performed the same functions, but without goto, but with alternative approaches ( break, continue, putting the code block into methods). There were, in fact, others, such as:
  • the difficulty of reading and understanding code that contains operators goto;
  • complication of code optimization for the compiler (and sometimes impossibility);
  • increasing the likelihood of creating subtle errors in the code.
For many, it is not a secret that in some programming languages ​​the operator gotofunctions quite successfully. However, programmers avoid using it. You can read about the reasons for this in one article on Habré . But why then leave it gotoin the list of reserved words? It's simple: for the future. If, for example, variables, methods, or classes are named all over the world in the Java code of developers goto, if this operator is returned in one of the future versions of Java, all the old code will break. To avoid such a scenario, gotoremained in the list of Java keywords, but does not carry any functionality. Perhaps someday gotohe will return to our ranks, but the likelihood of this is low.

Results

We have looked at the various jump operators in Java:
  1. return- completion of the method, return of the value from the method.
    • return value: methods that return values;
    • no return value: voidmethods.
  2. break— interruption of cycles, switch-case blocks.
    • with tags: cycles of different nesting;
    • without tags: switch-case block branches; interrupting the loop in which it was called.
  3. continue.
    • with tags: cycles of different nesting;
    • unlabeled: continuation of the loop in which it was called.
  4. goto.
    • is in the list of keywords, but is not used.
The takeaway from all of this is simple: it's best to favor the simplest approaches that make the code easier to read. Try not to overload the code with multi-level loops nested inside each other with an abundance of labels, breaks and continuations.Jump statements in Java - 3
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION