Skip to main content

Understanding Java's flow of execution

Posted by hellofadude on December 4, 2013 at 2:49 PM PST

Java uses conditional statements to determine the execution path. Conditional statements provide a way to determine the truth or falsehood of a conditional expression, by which we mean to describe expressions that make use of relational operators and such, and that are able to produce a boolean value.

These include the if-else statement, which is a control statement most commonly used to control the flow of execution, also the while, do-while, and for statements, which are mainly used to control iteration and loops, the return, break and continue statements, which allow us to perform unconditional branching and finally the switch statement, which, prior to Java SE 7 worked mainly with integral values and provides a way for multiway selection.

if-else statement

The if-else statement provides a way to control the flow or sequence of statements by allowing you to test for certain conditions within the conventions of a boolean expression. It is a way of saying if x == y then do z. Note the use of the relational equivalence operator which works with primitives as well as objects, though in the latter case it actually compares object references as opposed to the content of the object themselves. Here is an example of the use of an if-else statement that imitates a simple traffic control system:-

  public class TrafficLights {
      public static void main(String[] args) {
          boolean condition = false;
          if(condition) {
             System.out.println("Walk")
          } else {
             System.out.println("Don't walk")
          }
      }
   }
   /* Output
   Don't Walk
   *//

In the main(), the if statement is used to evaluate the boolean-expression, in this case, if the boolean variable condition happens to be true or false. If condition evaluates to true, it prints "Walk" to system console, otherwise, if it is false it prints "Don't walk". The placement of curly braces should be well noted, as a common error is when a programmer gets confused as to how to properly situate curly braces particularly when there is a subsequent else statement.

Curly braces are optional, without an else statement, otherwise an if statement should be properly enclosed within an open { and close } curly brace before any subsequent else statement.
We can extend the if-else statement in a manner that allows us to provide for several execution paths like so:-

  import java.util.Random;

  public class ThrowDice {
     public static void main(String[] args) {
         Random rand = new Random(8);
         for (int i = 1; i < 6; i++) {
              int spin = rand.nextInt(7);
              if(spin == 1) {
                  System.out.println(spin + ": Loser.. Low number");
              } else if(spin == 6) {
                  System.out.println(spin + ": Winner! High number");
              } else if (spin > 1 && spin < 6){
                  System.out.println(spin + ": Try again..");
              } else {
                  System.out.println(spin + ": Not allowed" );
              }
         }  
     }
  }
  /* Output
  1: Loser.. low number
  2: Try again..
  4: Try again..
  0: Not allowed
  6: Winner! High number
  *//

Here is a class that uses a random object to imitate a dice throwing game. A random number generator is set with a long seed, which is just a way of giving it an initial value to keep our results consistent.
The random object rand uses the nextInt() method to return a pseudorandom value between and including 0 and, but excluding 7. What this means is the value of our spin variable may be anything from 0 to 6, which does not strictly conform to the six sides of a standard die.

Note how we extend the use of the if-else statement to deal with a number of possible scenarios, depending on the number generated. An additional if is added to the else to test for the high and low numbers and everything else in-between. Also note the final else statement which acts as a default and deals the number 0. You may also wish to note the use of conditional and logical operators to test for values between 1 and 6, in this instance printing "Try again.." to the screen if spin is greater than 1 but less than 6.
Further, we place our if-else statement in a for loop that allows us to have 6 throws of the dice.

Iteration and looping

Iteration or looping is a way to allow certain code in your program be repeated multiple times. This is usually achieved by means of a sequence of quantities returned from a test condition. These quantities act in a way to determine the number of iterations required in your loop. Java uses the keywords while, do-while and for, to implement iteration statements.

while loop

The while loop evaluates an expression once, at the beginning of every iteration. It is of the form:-

     while(Boolean-expression)
        statement

The while statement continues until the boolean-expression evaluates to false. Here is a demonstration that prints a sequence of numbers to screen as long as the condition count < 10 evaluates to true.
    import java.util.Random;

    public class Counter {
       public static void main(String[] args) {
            Random rand = new Random(8);
            int count = rand.nextInt(10);
              while(count < 10) {
                System.out.println("count is " + count);
                count++;
            }     
       }
   }
    /* Output
    count is 4
    count is 5
    count is 6
    count is 7
    count is 8
    count is 9
    //*

The reader will note how it is necessary to manually increment the count variable within the while block, otherwise the test condition will never evaluate to false and then you might get into what we call an infinite loop.

do-while loop

The do-while loop works slightly differently from the while loop because it always executes the statement at least once, even if the test condition evaluates the false the first time. This is so, because the do-while evaluates the expression after the statement, like so:-

   do 
     statement
   while(Boolean-expression);

We could modify our Counter class to implement a do-while loop like this:-
   import java.util.Random;

   public class Counter {
       public static void main(String[] args) {
           Random rand = new Random(8);
           int count = rand.nextInt(10);
            do {
                 System.out.println("count = " + count);
                count++;
            } while(count < 10);
            
       }
    }
   /* Output
    count is 4
    count is 5
    count is 6
    count is 7
    count is 8
    count is 9
    //*

for loop

The for loop is one most commonly used for iteration and whose logic is divided into three distinct segments, each terminated by a semi-colon, that speak to the initialisation of a variable, a termination condition, and then a step - that is the actual incrementing of the variable proper after each iteration. It is of the form:-

  for(initialisation; termination-condition; step)
      statement

Here is an example using our Counter class:-

   import java.util.Random;

    public class Counter {
       public static void main(String[] args) {
           Random rand = new Random(8);
            for(int count = rand.nextInt(10); count < 10; count++) {
               System.out.println("count is " + count);
           }
       }
   }
     /* Output
    count is 4
    count is 5
    count is 6
    count is 7
    count is 8
    count is 9
    //*

As you will observe, incrementation is performed automatically, in a manner of speaking, at the end of every iteration so there is little need to manually increment the count variable within the loop as in the while and do-while loops.
With the for loop, You can define multiple variables separated by a comma operator like this:-
    import java.util.Random;

    public class Counter {
       public static void main(String[] args) {
           Random rand = new Random(8);
           for(int count = rand.nextInt(10), i = count * 2; count <
               10; count++, i = i - count ) {
               System.out.println("count = " + count + ", i is " + i);
             
           }
       }
    }
    /* Output
    count is 4, i is 8
    count is 5, i is 3
    count is 6, i is -3
    count is 7, i is -10
    count is 8, i is -18
    count is 9, i is -27
    *//

In the above example, we initialise two int variables count and i, separated by the comma operator. At each step, count is incremented by 1 while the i variable is divided by the current value of the count variable.

foreach syntax

Another variation of the for loop exists specifically for use with arrays and containers. Sometimes called the foreach syntax it allows you to count through a sequence of items in a container and looks like this:-

  for(type variable : arrayVariable)

Here is an example of a class using the foreach syntax:-
   import java.util.Random;

   public class ForEach {
       public static void main(String[] args) {
            Random rand = new Random(8);
            int[] count = new int[5];
            for(int i = 0; i < 5; i++) {
                 count[i] = rand.nextInt();
            }
            for(int x : count)
               System.out.println(x);
       }
   }
   /* Output
   count is 4
   count is 6
   count is 0
   count is 1
   count is 2
   *//

In this example, the for loop is first used to populate an array [ ] of int. The foreach syntax iterates through the array and assigns each element within to a variable x also of type int; in other words the variable x, holds the current element in the array. The foreach syntax is ideally suited to any method that returns an array.

Unconditional branching

Unconditional branching statements allow us to break from the current iteration in a loop or exit from some method without any test conditions. Java uses the keywords return, break and continue are used to achieve this effect.

return statement

The return statement is used to specify the return value of a method i.e. one that is not declared void, as well as causing the program to exit from that method with or without a return value:-

   static int Counter() {
       return ++count;
   }

The return statement causes the method to exit and returns control to the point where the method was invoked. A method declared as void has an implicit return so adding a return statement would be superfluous but not necessarily illegal.

break statement

The break statement is used to break out of a loop without executing the rest of the statements; It can be used with either of the for, do, do-while or switch statements. To terminate a loop, you simply place the break keyword at the point where you wish for this to happen:-

   import java.util.Random;

   public class BreakLoop {
     
     public static void main(String[] args) {
        Random rand = new Random(6);
        for(int i = 0; i < 6; i++) {
            int x = rand.nextInt(6);
            if(x == i) {
               System.out.println("x == i " + "x is " + x + ", i is "
                                 + i + ", breaking out of loop!");
               break;
            }
            System.out.println("x != i: " + "x is " + x + ", i is " + i);
         }
      } 
   }
   /* Output
   x != i: x is 1, i is 0
   x != i: x is 0, i is 1
   x == i: x is 2, i is 2, breaking out of loop!
   *//

The break statement can also be used in the while and do-while loops, but in this example, it is used to break out of the for loop if x == i, otherwise, it carries on until termination condition. In a situation where we might have nested loops i.e. loops within loops, the break statement will terminate the inner most loop returning control to the outermost loop. To terminate the outermost loop from within an inner loop, we may use a labelled break statement like so:-
     public class LabelledBreak {
         public static void main(String[] args) {
            outer:
            for(int i=0; i < 10; i++) {
                for(int x=i * 10; x < 100; x++) {
                   if (x % 9 == 0) break outer;
                           System.out.print(x + " ");
                  
                }
            }
         }
     }
     /* Output
     10 11 12 13 14 15 16 17
     *//

The label outer is an identifier used to mark the start of the outermost for loop, which signals the point where the break statement must terminate. This is to say control is returned to statement immediately following the labelled statement. From the example, it is clear that x never gets 100 as the break statement terminates the loop when there is no remainder from the modulus operator. Note the use of the print statement which prints horizontally across the screen as opposed to the println statement which prints vertically.

continue statement

The continue statement causes control to return to the beginning of the next iteration of the innermost loop, without completing the current iteration. Unlike the break statement it does not break out of the loop completely.

     public class ContinueStatement {
         public static void main(String[] args) {
             for(int i = 0; i < 100; i++) {                
                 if(i % 10 != 0) continue; //Top of the loop
                         System.out.println(i + " ");
             }
         }
     }
     /* Output
     10 20 30 40 50 60 70 80 90
     *//
 

The continue statement in this example, is used to exit the current iteration if the condition i % 10 is not equal to 0, and only prints when the value of the expression evaluates to 0.

switch statement

The switch statement is a kind of selection statement that allows you to select from a number of possible execution paths. The switch statement works with integral values like int, char primitive types, as well as enumerated types, the String class and certain other wrapper classes.

The following code uses a switch statement to print the value of i to screen:-

   public class SwitchStatement {
      public static void main(String[] args) {
         for(int i = 0; i < 6; i++) {
             switch(i) {
                case 1: System.out.println("i is " + i); break;
                case 2: System.out.println("i is " + i); break;
                case 3: System.out.println("i is " + i); break;
                case 4: System.out.println("i is " + i); break;
                case 5: System.out.println("i is " + i); break;
                default: System.out.println("i is " + i);
             }
          }
       }
    }
    /* Output
    i is 0
    i is 1
    i is 2
    i is 3
    i is 4
    i is 5
    *//

You may observe the body of a switch statement is enclosed between curly braces that comprise the switch block. Following the switch, One may have multiple case labels whereby a matching case is executed based on the evaluation of the test expression.

The preceding example compares the value of i with each case label and prints the appropriate value to screen, so for instance, if i == 1, the statements in case 1 are executed.

Note that each case ends with a break clause, which causes execution to jump to the end of the switch block. Also note the last statement which is the default statement, handles all scenarios not explicitly provided for in any of the case labels and does not require a break sytatement, even though it would comprise no ill-effect were you to choose to include one; in this case, the default statements prints 0 to screen.

It is also possible to stack case labels in a way that provides multiple matches for a particular piece of code. Run the following example to see the result:-

   public class SwitchStatement2 {
      public static void main(String[] args) {
           for(int i = 0; i < 10; i++) {
                switch(i) {
                   case 1:
                   case 3:
                   case 5:
                   case 7:
                   case 9: System.out.println("odd number " + i);
                           break;
                   default: System.out.println("even number " + i);
                }
             }
         }
     }

It is essential to put a break statement at the end of a particular case otherwise control will simply drop through and continue processing until a break is encountered. In the above example, the cases are stacked on top of the other when i is an odd number, otherwise the default statement is used to print out even numbers.

Summary

We have fully explored the basics of controlling the flow of execution in your Java program. We should by now be well acquainted with how to use the if-else statements to control flow, the switch statement for multiway selection, implementing loops like for, while and the do-while, terminating loops using the break statement, breaking out of the current iteration with the continue statement and how to use the return statement to return required values in methods that specify a return type.

contact me @ kaseosime@btinternet.com