Chapter 3 - Java for Beginners Course

Branching Statements

Under certain conditions, we might need to stop a loop, or proceed with the next iteration straight-away omitting the remainder of a block of code, or return from a method.

The branching statements allow us to do this, and we’ve already seen one of them in previous sections.

The return statement

This statement exits the method that is currently executing and returns the provided value (if any) to the invoking method. So far, all of the methods we’ve seen, for example in the Airplane class or in the Door class don’t return any values as they specify a void return type in their methods.

The return statement:

  • Must be defined for methods with a non-void return type. In this case, the return statement must have a value, for example, return x; and the data type must correspond to the return type of the method.

  • Is optional for methods with a void return type. If provided, the return statement must not have a value, for example, return;.

  • Any method can have more than one return statement, although certain rules apply that we’ll cover in a later course.

The return statement is a topic on its own and we are covering the basics only in this section!
The return statement works at a method level.

As an example, let’s define a PerimeterCalculator class:

public class PerimeterCalculator {

    public void printSquarePerimeter(int side) {
        if (side <= 0) {
            return;
        }
        System.out.println("The perimeter of a square of side " + side + " is: " + (side * 4));
        return;
    }

    public int squarePerimeter(int side) {
        int perimeter = 4 * side;
        return perimeter;
    }

}

Here, we have a class with two methods, one that prints out the perimeter of a square if the side is greater than 0 (printSquarePerimeter), and the other one that calculates the perimeter and returns the calculated value (squarePerimeter).

Let’s use it to see what we get:

In the example project, check the BranchingStatementsApp class.
// Examples of the return statement - check the methods in the PerimeterCalculator class
PerimeterCalculator calculator = new PerimeterCalculator();

// first, let's print out the perimeter of a square of side 4:
calculator.printSquarePerimeter(4);

// next, let's try printing out the perimeter of a square of side -1, in this case,
// nothing should be printed out:
calculator.printSquarePerimeter(-1);

// now, let's try using the squarePerimeter method and store the returned value in
// the result variable:
int result = calculator.squarePerimeter(2);
System.out.println("A square of side 2 has a perimeter of: " + result);

Output:

The perimeter of a square of side 4 is: 16
A square of side 2 has a perimeter of: 8

Analysing the method calls to our PerimeterCalculator

In the first two method calls, we are invoking the calculator.printSquarePerimeter(…​) method that has a void return type. As a result, we don’t get any value back, hence we cannot assign its result to a variable (because in effect, there is no result).

The printSquarePerimeter method specifies a return; statement at the end, which is optional. However, it also specifies a return; statement at the beginning, after checking if the side parameter is valid.

In the second invocation of the method, calculator.printSquarePerimeter(-1), the side parameter is negative and hence the condition of the if statement is true. This initial return; statement causes the method to exit, and as a result the message isn’t printed out in that case. The execution continues on the next line from where we invoked the method, in our case, int result = calculator.squarePerimeter(2);.

In the last invocation, we are calling method calculator.squarePerimeter(2). This method has a non-void return type, in our case, it indicates that it will return an int value and as such, the method must have a return statement with an int value. In the example, we have return perimeter; where perimeter is a variable of type int.

As the method returns a value, we can make use of this variable as desired. In our case, we are assigning the value to the result variable, which we then print out as our second message in our output.

The break statement

This statement has already been introduced in the switch statement section. As mentioned there, we can use it to terminate the execution of the following control flow statements: switch, for, while and do-while.

The break statement works at a control flow statement level and it cannot be used with if statements.

For example:

int n = 10;
int energy = 3;
for (int i = 0; i < n; i++) {
    if (energy > 0) {
        System.out.println("I still have " + energy + " energy left!");
        energy--;
    } else {
        System.out.println("I can't do this anymore!");
        break;
    }
}

Output:

I still have 3 energy left!
I still have 2 energy left!
I still have 1 energy left!
I can't do this anymore!

Analysing the break statement example

In our example above, we see that we have a variable i that is iterating from 0 to 10 (the value of n) and we expect 10 iterations in that case. However, as we have a break statement, the loop is terminated beforehand, in our case, we base our decision on an energy variable that is being decreased on every iteration until it reaches a value of 0.

Once the energy value reaches a value of 0, our else case is executed and the break; clause is called, causing our loop to terminate.

The example is made up to illustrate the usage of the break clause. You could argue, that based on what the example is doing, we could have written this instead:

int energy = 3;
for (int i = 0; i < energy; i++) {
    System.out.println("I still have " + (energy - i) + " energy left!");
}
System.out.println("I can't do this anymore!");

And you would be right, this generates the same result as in the code before.

In general, loops/statements with a break clause can be re-written such that there is no break statement. However, depending on the case, and in more complex cases than in our example above, it can be more readable to make use of the break statement.

The continue statement

The continue statement allows us to stop the current iteration of a loop and skip to the next iteration. It can be used with for, while and do-while statements.

The continue statement works at a control flow statement level and it can only be used with looping statements.

For example, the following code will print out the even numbers from 0 to m (exclusive):

int m = 8;
for (int i = 0; i < m; i++) {
    // if the number is odd
    if (i % 2 == 1) {
        continue;
    }
    System.out.println("The next even number is: " + i);
}

Output:

The next even number is: 0
The next even number is: 2
The next even number is: 4
The next even number is: 6

Analysing the continue statement example

In the example code, we are checking if the current value of i is odd. We do this by checking the remainder of the division by 2, an odd number will have a remainder of 1, hence our if condition is i % 2 == 1.

If the number is odd, we’ll execute the continue statement, and this causes the remainder of the block of code of the for loop to be skipped and we move to the next iteration.

By doing so, the increment statement of the for loop is executed, in our case, i++ and our loop condition is verified before the next iteration starts.

This causes that:

  • In our first iteration, i is 0, and our if condition is false as 0 % 2 equals 0 and not 1. In this case, the continue statement is not executed and we print out the message The next even number is: 0.

  • In our second iteration, i is 1. In this case, our if condition is true as 1 % 2 equals 1, causing the continue statement to be triggered and hence the rest of our for loop’s block of code is skipped. As a result, a message with number 1 isn’t printed out.

  • An so on…​

Similar to the example of the break clause, you could argue that our example code could have been written like this:

int m = 8;
for (int i = 0; i < m; i += 2) {
    System.out.println("The next even number is: " + i);
}

And again, you would be right, the output of both is the same.

Similarly to the case with break statements, in general, loops with a continue clause can be re-written such that there is no continue statement. However, depending on the case, and in more complex cases than in our example above, it can be more readable to make use of the continue statement.

About nesting

If you have nested loops, the break and continue statements operate on the innermost loop they encounter.

For example, if you have a nested for loop inside a while loop, and you add a break statement inside the for loop, then the for loop will be terminated, as in the code below:

int j = 1;
while (j <= 2) {
    System.out.println("The outer loop is on iteration: " + j);
    j++;

    for (int k = 1; k <= 4; k++) {
        System.out.println("    The inner loop is on iteration: " + k);
        break;
    }
}

Output:

The outer loop is on iteration: 1
    The inner loop is on iteration: 1
The outer loop is on iteration: 2
    The inner loop is on iteration: 1

Analysing the nested loop example

In the code above, we have an outer while loop that iterates twice (with j having the values of 1 and 2), and an inner for loop that iterates k from 1 to 4.

Ignoring the break clause for a moment, we would expect the outer loop’s message twice (which is printed out as expected), and the inner loop’s message four times in each iteration of the outer loop.

Now, taking the break clause into consideration, it terminates the innermost loop it finds. In the example, this is the for loop which is terminated early, more precisely, during the first iteration of the inner loop.

Try moving the break statement outside of the for loop, both before and after the for loop and see what results you get!

There is a variant of the break and continue statements, called labelled break and labelled continue that we’ll cover in a future course.