Chapter 8: More Control Structures:

We have already looked at some control structures such as the if statements, the for loop and the while loop. We also looked at the use of the break statement which allows you to come out of a loop before the loop is completed (the example of the infinite loop), the break statement inside of an if statement which does the same thing – i.e. allows you to exit the if statement before it is completed, and the return statement that allows to exit a loop as well (in fact terminate the loop at some point).

We would now look at the do loop, the switch statement, the continue statement and the exception handling.

Exceptions:

When a program performs an illegal operation, an exception occurs. The exception occurs during the execution of the program, not during the compilation. When an exception occurs, the program may terminate, but most often, it would behave badly – giving wrong results, doing something it was not supposed to do, etc. When an exception occurs, there is a way to let you handle it called the exception handler.

Exceptions occur among other places, when we try to divide or modulo by 0, or try to use an object that was initialized to null.

To catch an exception, we have to anticipate where it is likely that an error may occur and then use a try block and catch block to catch that error. A try block have the following structure:

try

block

catch

block

Inside the try, a series of statements would be placed that may cause the exception. Inside of the catch block, a series of statement that specifies what to do if the exception is thrown (occurs). We could print an error message in the catch block regarding the type of error. In the catch block, we would specify the exception type that is to be handled. Also, a try and catch block together form one single statement. Example:

try

{

quotient = dividend / divisor;

}

catch (ArithmeticException e)

{

System.out.println(“Error: Division by 0”);

}

If the divisor is 0, the try block will throw an exception which will be caught by the catch block. If is not 0, then the catch block will not be executed. Either way, the next statement in the program will be executed, unless if in the catch block, we terminated the program.

Caution:

  1. Try not declare variable inside of a try-catch block and then attempt to extract the value of that variable outside of the block. That variable is local.
  1. Do not declare a variable immediately before a try-catch block and then attempt to use it inside of the block. You will get compiler error. If you must do this, initialize the variable.

In the above case, if divisor was 0, we could actually see this by using the following statement:

e.getMessage() //which will print / by zero

e in this case is an exception object created by Java. And e could be any name you wish it to be.

After we get an error, we may want to terminate the program. To do so we call the System.exit() method, example:

try

{

quotient = dividend / divisor;

}

catch (ArithmeticException e)

{

System.out.println(“Error: Division by 0”);

System.exit(-1);

}

The return statement will only terminate the program if the try-catch block was in the main method.

Converting string to integer:

We use the try-catch block here because a user may enter “ABC” and try to convert this to integer. Furthermore, it is good programming to enable the user to re-enter a value. The user may make a mistake when typing, so he/she should be given chances to re-enter the value. The following code will do:

while (true)

{

SimpleIO.prompt(“Enter an integer: “);

String userInput = SimpleIO.readLine();

try

{

n = Integer.parseInt(userInput);

break;

}

catch (NumberFormatException e)

{

System.out.println(“You did not enter an integer: Try again!!!”);

}

}

There are two types of exceptions – checked and unchecked.

  1. The checked exception must be handled by the programmer. If we don’t, the compiler will produce and error. An example is the use of the Thread.sleep() method that requires one parameter. This method is used to delay a program execution by the amount of time supplied as the argument (in milliseconds). Whenever this method is used, it is required to be placed inside of a try-catch block:

try

{

Thread.sleep(1000);

}

catch (InterruptedException e)

{

}

  1. The unchecked could be ignored by the programmer. These may occur in many places in a program so it is advisable to check for them. Exceptions of this type are ArithmeticException, NullPointerException, and NumberFormatException among others.

Switch Statement:

These are used in many cases as a substitute for the cascaded if statement and of course to shorten the if statement. An example:

if (day == 1)

System.out.println(“Sunday”);

else if (day == 2)

System.out.println(“Monday”);

else if (day == 3)

System.out.println(“Tuesday”);

else if (day == 4)

System.out.println(“Wednesday”);

else if (day == 5)

System.out.println(“Thursday”);

else if (day == 6)

System.out.println(“Friday”);

else if (day == 7)

System.out.println(“Saturday”);

Using a switch statement we could write:

switch (day)

{

case 1: System.out.println(“Sunday”);

break;

case 2: System.out.println(“Monday”);

break;

case 3: System.out.println(“Tuesday”);

break;

case 4: System.out.println(“Wednesday”);

break;

case 5: System.out.println(“Thursday”);

break;

case 6: System.out.println(“Friday”);

break;

case 7: System.out.println(“Saturday”);

break;

}

The format of the switch statement is therefore:

switch (controlling expression)

{

case case_labels: statements; //here we have case_labels or constant expression

break;

}

The controlling expression will be compared with the case_labels (or constant expression that could be a constant like 10 or an expression that compiler can evaluate such as 10 + 25 * 12 – but no variables must be involved) and if there is a match, then the following statements would be executed, then the break statement. Note: these case labels can go in any order, but it is illegal to have the same value appear twice as a case_label or constant expression. This would mean that we exit the switch statement at this point. For the controlling expression, we can only use char, int, byte or short data types – NO OTHERS including objects such as strings.

Combining case labels:

switch (day)

{

case 1:

case 7: System.out.println(“Weekend”);

break;

case 2:

case 3:

case 4:

case 5:

case 6: System.out.println(“Weekday”);

break;

}

Or:

switch (day)

{

case 1: case 7:

System.out.println(“Weekend”);

break;

case 2: case 3: case 4: case 5: case 6:

System.out.println(“Weekday”);

break;

}

We could use the default key word to do something if a controlling expression was not found to be matching example:

switch (day)

{

case 1: case 7:

System.out.println(“Weekend”);

break;

case 2: case 3: case 4: case 5: case 6:

System.out.println(“Weekday”);

break;

default:

System.out.println(“Not a valid entry.”);

break;

}

A switch statement is much easier to read than a cascaded if statement. Also, it is faster to execute because not all cases need to be checked. However, due to its limitations, the switch statement cannot entirely replace the if statement. When we want to compare objects such as strings, we would need to use the if statement. Also other cases exist where the if statement is indispensable.

The do statement:

This is very similar to the while loop except that the do loop is executed at least once. The structure is:

do

{

statements;

}while (expression/condition);

A while loop is:

while( expression/condition)

{

statements;

}

As could be seen, a do loop is therefore very much like a reversed while loop, because in a while loop, before going in, the condition/expression is tested and if it is true, then and only then the loop is entered.

Not so for the do loop. In fact, this is the only difference between a do loop and a while loop.

The continue Statement:

The continue statement is similar to the break with the exception that the continue statement do not allow a break out of the loop at that point, but causes the program to jump to the end of the loop. That is, the loop continues to execute but part of it is skipped. So whereas the break statement transfers control just past the loop, continue transfers control to just before the end of the loop. Also, break could be used both in a loop and an if (switch) whereas continue can only be used inside of a loop.

Nested Loops:

Nested loops are quite common in Java and other programming languages. It’s structure is to put one loop inside of another. Many of the sorting routine consist of nested loops. Also if we want to create a Matrix, we use nested loops. An example of the use of nested loop to sort an array of integer in ascending order:

int a[] = {10, 5, 6, 3, 1};

n = a.length;

for (int i = 0; i < n; i++)

{

int smallest = a[i];

int index = i;

for (int j = 0; j < n; j++)

{

if (smallest > a[j])

{

smallest = a[j];

index = j;

}

if (smallest > a[i])

{

int temp = a[i];

a[i] = smallest;

a[index] = temp;

}

}

}

Note: If we have nested structures – loops or loops with switch, and these some carry break statements, the break will allow us to come out of the structure with the break and not the entire nested structure. For example, if a break was in an inner loop, then control will transfer to the outer loop and not completely out of both loops. There are times however, when we want to break out of both loops. We can do this by using the labeled break. To implement this, we need to create a label just before the loop we need to come out of and when we break, we use the name of this label after the word break. The structure is:

Come_out_here: //label – note the use of the colon at the end of the label

for(;;)

for(;;)

{

statements;

if (expression)

break Come_out_here;

}

The labeled continue statement work similar to the labeled break statement. This statement must precede one of the loops. Then execution will jump to the end of that loop without causing the loop to terminate.

1