|
JavaFAQ Home » Java Lectures by Anatoliy Malyarenko

Control flow statements
Abstract
Contents of the lecture.
- The while and do-while statements.
- The for statement.
- The if/else statements.
- The switch statement.
- Exception handling statements.
- Branching statements.
- Summary of control flow statements.
Introduction
When you write a program, you type statements into a file.
Without control flow
statements, the interpreter executes these statements in the order they appear in the file
from left to right, top to bottom.
You can use control flow statements in your programs
to conditionally execute statements, to repeatedly execute a block of statements, and to
otherwise change the normal, sequential flow of control. For example, in the following code
snippet, the if statement conditionally executes the System.out.println statement within
the braces, based on the return value of Character.isUpperCase(aChar):
| Code: |
char c;
...
if (Character.isUpperCase(aChar)) {
System.out.println("The character " + aChar
+ " is upper case.");
}
|
The Java programming language provides several control flow statements, which are
listed in the following table.
| Statement type |
Keyword |
| looping |
while, do-while, for |
| decision making |
if-else, switch-case |
| exception handling |
try-catch-finally, throw |
| branching |
break, continue, label:, return |
Later you will see the following notation to describe the general form of a control flow
statement:
| Code: |
control flow statement details {
statement(s)
}
|
Technically, the braces, { and }, are not required if the block contains only one statement.
However, we recommend that you always use { and }, because the code is easier to read and
it helps to prevent errors when modifying code.
The while and do-while statements
You use a while statement to continually execute a block of statements while a condition
remains true. The general syntax of the while statement is:
| Code: |
while (expression) {
statement
}
|
First, the while statement evaluates expression, which must return a boolean value. If the
expression returns true, then the while statement executes the statement(s) associated with
it. The while statement continues testing the expression and executing its block until the
expression returns false.
The example program shown below, called WhileDemo, uses a while statement to step
through the characters of a string, appending each character from the string to the end of a
string buffer until it encounters the letter g.
| Code: |
public class WhileDemo {
public static void main(String[] args) {
String copyFromMe =
"Copy this string until you " +
"encounter the letter ’g’.";
StringBuffer copyToMe = new StringBuffer();
int i = 0;
char c = copyFromMe.charAt(i);
while (c != ’g’) {
copyToMe.append(c);
c = copyFromMe.charAt(++i);
}
System.out.println(copyToMe);
}
}
|
The value printed by the last line is: Copy this strin.
The Java programming language provides another statement that is similar to the while
statement --the do-while statement. The general syntax of the do-while is:
| Code: |
do
statement(s)
while (expression);
|
Instead of evaluating the expression at the top of the loop, do-while evaluates the
expression at the bottom. Thus the statements associated with a do-while are executed at
least once.
Here's the previous program rewritten to use do-while and renamed to DoWhileDemo:
| Code: |
public class DoWhileDemo {
public static void main(String[] args) {
String copyFromMe =
"Copy this string until you " +
"encounter the letter ’g’.";
StringBuffer copyToMe = new StringBuffer();
int i = 0;
char c = copyFromMe.charAt(i);
do {
copyToMe.append(c);
c = copyFromMe.charAt(++i);
} while (c != ’g’);
System.out.println(copyToMe);
}
}
|
The value printed by the last line is: Copy this strin.
The for statement
The for statement provides a compact way to iterate over a range of values. The general
form of the for statement can be expressed like this:
| Code: |
for (initialisation; termination; increment) {
statement
}
|
The initialisation is an expression that initialises the loop -- it's executed once
at the beginning of the loop. The termination expression determines when to terminate the
loop. This expression is evaluated at the top of each iteration of the loop. When the expression
evaluates to false, the loop terminates. Finally, increment is an expression that gets invoked
after each iteration through the loop. All these components are optional. In fact, to write an
infinite loop, you omit all three expressions:
| Code: |
for ( ; ; ) { // infinite loop
...
}
|
Often for loops are used to iterate over the elements in an array, or the characters in a
string. The following sample, ForDemo, uses a for statement to iterate over the elements of
an array and print them:
| Code: |
public class ForDemo {
public static void main(String[] args) {
int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076,
2000, 8, 622, 127 };
for (int i = 0; i < arrayOfInts.length; i++) {
System.out.print(arrayOfInts[i] + " ");
}
System.out.println();
}
}
|
The output of the program is: 32 87 3 589 12 1076 2000 8 622 127.
Note that you can declare a local variable within the initialisation expression of a for
loop. The scope of this variable extends from its declaration to the end of the block governed
by the for statement so it can be used in the termination and increment expressions as well.
If the variable that controls a for loop is not needed outside of the loop, it's best to declare
the variable in the initialisation expression. The names i, j, and k are often used to control
for loops; declaring them within the for loop initialisation expression limits their life-span and
reduces errors.
The if/else statements
The if statement enables your program to selectively execute other statements, based
on some criteria. For example, suppose that your program prints debugging information,
based on the value of a boolean variable named DEBUG. If DEBUG is true, your program prints
debugging information, such as the value of a variable, such as x. Otherwise, your program
proceeds normally. A segment of code to implement this might look like this:
| Code: |
if (DEBUG) {
System.out.println("DEBUG: x = " + x);
}
|
This is the simplest version of the if statement: The block governed by the if is
executed if a condition is true. Generally, the simple form of if can be written like this:
| Code: |
if (expression) {
statement(s)
}
|
What if you want to perform a different set of statements if the expression is false? You
use the else statement for that. Consider another example. Suppose that your program needs
to perform different actions depending on whether the user clicks the OK button or another
button in an alert window. Your program could do this by using an if statement along with an
else statement:
| Code: |
. . .
// response is either OK or CANCEL depending
// on the button that the user pressed
. . .
if (response == OK) {
// code to perform OK action
} else {
// code to perform Cancel action
}
|
The else block is executed if the if part is false. Another form of the else statement,
else if, executes a statement based on another expression. An if statement can have
any number of companion else if statements but only one else. Following is a program,
IfElseDemo, that assigns a grade based on the value of a test score: an A for a score of 90%
or above, a B for a score of 80% or above, and so on:
| Code: |
public class IfElseDemo {
public static void main(String[] args) {
int testscore = 76;
char grade;
if (testscore >= 90) {
grade = ’A’;
} else if (testscore >= 80) {
grade = ’B’;
} else if (testscore >= 70) {
grade = ’C’;
} else if (testscore >= 60) {
grade = ’D’;
} else {
grade = ’F’;
}
System.out.println("Grade = " + grade);
}
}
|
The output from this program is:
Grade = C
You may have noticed that the value of testscore can satisfy more than one of the
expressions in the compound if statement: 76 >= 70 and 76 >= 60. However, as the runtime
system processes a compound if statement such as this one, once a condition is satisfied,
the appropriate statements are executed (grade = ’C’ , and control passes out of the if
statement without evaluating the remaining conditions.
The Java programming language supports an operator, ?:, that is a compact version of
an if statement. Recall this statement from the MaxVariablesDemo program:
| Code: |
if (Character.isUpperCase(aChar)) {
System.out.println("The character " + aChar +
" is upper case.");
} else {
System.out.println("The character " + aChar +
" is lower case.");
}
|
Here's how you could rewrite that statement using the ?: operator:
| Code: |
System.out.println("The character " + aChar +
" is " + (Character.isUpperCase(aChar)
? "upper" : "lower") + "case.");
|
The ?: operator returns the string "upper" if the isUpperCase method returns true.
Otherwise, it returns the string "lower". The result is concatenated with other parts of a
message to be displayed. Using ?: makes sense here because the if statement is secondary
to the call to the println method. Once you get used to this construct, it also makes the code
easier to read.
The switch statement
Use the switch statement to conditionally perform statements based on an integer
expression. Following is a sample program, SwitchDemo, that declares an integer named
month whose value supposedly represents the month in a date. The program displays the
name of the month, based on the value of month, using the switch statement:
| Code: |
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
switch (month) {
case 1: System.out.println("January"); break;
case 2: System.out.println("February"); break;
case 3: System.out.println("March"); break;
case 4: System.out.println("April"); break;
case 5: System.out.println("May"); break;
case 6: System.out.println("June"); break;
case 7: System.out.println("July"); break;
case 8: System.out.println("August"); break;
case 9: System.out.println("September"); break;
case 10: System.out.println("October"); break;
case 11: System.out.println("November"); break;
case 12: System.out.println("December"); break;
}
}
}
|
The switch statement evaluates its expression, in this case the value of month, and
executes the appropriate case statement. Thus, the output of the program is: August. Of
course, you could implement this by using an if statement:
| Code: |
int month = 8;
if (month == 1) {
System.out.println("January");
} else if (month == 2) {
System.out.println("February");
} . . . // and so on
|
Deciding whether to use an if statement or a switch statement is a judgment call. You
can decide which to use, based on readability and other factors. An if statement can be used
to make decisions based on ranges of values or conditions, whereas a switch statement can
make decisions based only on a single integer value. Also, the value provided to each case
statement must be unique.
Another point of interest in the switch statement is the break statement after each
case. Each break statement terminates the enclosing switch statement, and the flow of
control continues with the first statement following the switch block. The break statements
are necessary because without them, the case statements fall through. That is, without an
explicit break, control will flow sequentially through subsequent case statements. Following
is an example, SwitchDemo2, which illustrates why it might be useful to have case statements
fall through:
| Code: |
public class SwitchDemo2 {
public static void main(String[] args) {
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) )
numDays = 29;
else
numDays = 28;
break;
}
System.out.println("Number of Days = " +
numDays);
}
}
|
The output from this program is:
Number of Days = 29
Technically, the final break is not required because flow would fall out of the switch
statement anyway. However, we recommend using a break for the last case statement just in
case you need to add more case statements at a later date. This makes modifying the code
easier and less error-prone.
You will see break used to terminate loops in branching statements.
Finally, you can use the default statement at the end of the switch to handle all values
that aren't explicitly handled by one of the case statements.
| Code: |
int month = 8;
. . .
switch (month) {
case 1: System.out.println("January"); break;
case 2: System.out.println("February"); break;
case 3: System.out.println("March"); break;
case 4: System.out.println("April"); break;
case 5: System.out.println("May"); break;
case 6: System.out.println("June"); break;
case 7: System.out.println("July"); break;
case 8: System.out.println("August"); break;
case 9: System.out.println("September"); break;
case 10: System.out.println("October"); break;
case 11: System.out.println("November"); break;
case 12: System.out.println("December"); break;
default: System.out.println("Hey, that’s not a valid month!"); break;
}
|
Exception handling statements
The Java programming language provides a mechanism known as exceptions to help
programs report and handle errors. When an error occurs, the program throws an exception.
What does this mean? It means that the normal flow of the program is interrupted and that the
runtime environment attempts to find an exception handler -- a block of code that can handle
a particular type of error. The exception handler can attempt to recover from the error or, if it
determines that the error is unrecoverable, provide a gentle exit from the program.
Three statements play a part in handling exceptions:
- The try statement identifies a block of statements within which an exception might be
thrown.
- The catch statement must be associated with a try statement and identifies a block of
statements that can handle a particular type of exception. The statements are executed if an exception of a particular type occurs within the try block.
- The finally statement must be associated with a try statement and identifies a block of
statements that are executed regardless of whether or not an error occurs within the try
block.
Here's the general form of these statements:
| Code: |
try {
statement(s)
} catch (exceptiontype name) {<br />
statement(s)
} finally {
statement(s)
}
|
This has been a brief overview of the statements provided by the Java programming
language used in reporting and handling errors. However, other factors and considerations,
such as the difference between runtime and checked exceptions and the hierarchy of
exceptions classes, which represent various types of exceptions, play a role in using the
exception mechanism.
Branching statements
The Java programming language supports three branching statements:
- The break statement.
- The continue statement.
- The return statement.
The break statement and the continue statement, which are covered next, can be used
with or without a label. A label is an identifier placed before a statement. The label is followed
by a colon ( :
statementName: someJavaStatement;
You'll see an example of a label within the context of a program in the next section.
The break statement
The break statement has two forms: unlabeled and labeled. You saw the unlabeled
form of the break statement used with switch earlier. As noted there, an unlabeled break
terminates the enclosing switch statement, and flow of control transfers to the statement
immediately following the switch. You can also use the unlabeled form of the break statement
to terminate a for, while, or do-while loop. The following sample program, BreakDemo,
contains a for loop that searches for a particular value within an array:
| Code: |
public class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts = 32, 87, 3, 589, 12, 1076,
2000, 8, 622, 127 ;
int searchfor = 12;
int i = 0;
boolean foundIt = false;
for ( ; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor +
" at index " + i);
} else {
System.out.println(searchfor +
"not in the array");
}
}
}
|
The break statement terminates the for loop when the value is found. The flow of
control transfers to the statement following the enclosing for, which is the print statement at
the end of the program.
The output of this program is:
Found 12 at index 4
The unlabeled form of the break statement is used to terminate the innermost switch,
for, while, or do-while; the labeled form terminates an outer statement, which is identified
by the label specified in the break statement. The following program, BreakWithLabelDemo,
is similar to the previous one, but it searches for a value in a two-dimensional array. Two
nested for loops traverse the array. When the value is found, a labeled break terminates the
statement labeled search, which is the outer for loop:
| Code: |
public class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] arrayOfInts = { { 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i = 0;
int j = 0;
boolean foundIt = false;
search:
for ( ; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
if (foundIt) {
System.out.println("Found " + searchfor +
" at " + i + ", " + j);
} else {
System.out.println(searchfor +
"not in the array");
}
}
}
|
The output of this program is:
Found 12 at 1, 0
This syntax can be a little confusing. The break statement terminates the labeled
statement; it does not transfer the flow of control to the label. The flow of control transfers
to the statement immediately following the labeled (terminated) statement.
The continue statement
You use the continue statement to skip the current iteration of a for, while, or
do-while loop.
The unlabeled form skips to the end of the innermost loop's body and
evaluates the boolean expression that controls the loop, basically skipping the remainder of
this iteration of the loop. The following program, ContinueDemo, steps through a string buffer
checking each letter. If the current character is not a p, the continue statement skips the rest
of the loop and proceeds to the next character. If it is a p, the program increments a counter,
and converts the p to an uppercase letter.
| Code: |
public class ContinueDemo {
public static void main(String[] args) {
StringBuffer searchMe = new StringBuffer(
"peter piper picked a peck of pickled peppers");
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
//interested only in p’s
if (searchMe.charAt(i) != ’p’)
continue;
//process p’s
numPs++;
searchMe.setCharAt(i, ’P’);
}
System.out.println("Found " + numPs +
" p’s in the string.");
System.out.println(searchMe);
}
}
|
Here is the output of this program:
Found 9 p's in the string.
Peter PiPer Picked a Peck of Pickled PePPers
The labeled form of the continue statement skips the current iteration of an outer loop
marked with the given label. The following example program, ContinueWithLabelDemo, uses
nested loops to search for a substring within another string. Two nested loops are required: one to iterate over the substring and one to iterate over the string being searched. This
program uses the labeled form of continue to skip an iteration in the outer loop:
| Code: |
public class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) !=
substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" :
"Didn’t find it");
}
}
|
Here is the output from this program:
Found it
The return statement
The last of Java's branching statements is the return statement. You use return to exit
from the current method. The flow of control returns to the statement that follows the original
method call. The return statement has two forms: one that returns a value and one that
doesn't. To return a value, simply put the value (or an expression that calculates the value)
after the return keyword:
return ++count;
The data type of the value returned by return must match the type of the method's
declared return value. When a method is declared void, use the form of return that doesn't
return a value:
return;
Summary of control flow statements
For controlling the flow of a program, the Java programming language has three loop
constructs, a flexible if-else statement, a switch statement, exception-handling statements,
and branching statements.
Use the while statement to loop over a block of statements while a boolean expression
remains true. The expression is evaluated at the top of the loop.
| Code: |
while (boolean expression) {
statement(s)
}
|
Use the do-while statement to loop over a block of statements while a boolean
expression remains true. The expression is evaluated at the bottom of the loop, so the
statements within the do-while block execute at least once:
| Code: |
do {
statement(s)
} while (expression);
|
The for statement loops over a block of statements and includes an initialisation
expression, a termination condition expression, and an increment expression.
| Code: |
for (initialization ; termination ; increment) {
statement(s)
}
|
The Java programming language has two decision-making statements: if-else and
switch. The more general-purpose statement is if; use switch to make multiple-choice
decisions based on a single integer value. The following is the most basic if statement whose
single statement block is executed if the boolean expression is true:
| Code: |
if (boolean expression) {
statement(s)
}
|
Here's an if statement with a companion else statement. The if statement executes
the first block if the boolean expression is true; otherwise, it executes the second block:
| Code: |
if (boolean expression) {
statement(s)
} else {
statement(s)
}
|
You can use else if to construct compound if statements:
| Code: |
if (boolean expression) {
statement(s)
} else if (boolean expression) {
statement(s)
} else if (boolean expression) {
statement(s)
} else {
statement(s)
}
|
The switch statement evaluates an integer expression and executes the appropriate
case statement.
| Code: |
switch (integer expression) {
case integer expression:
statement(s)
break;
...
default:
statement(s)
break;
}
|
Use the try, catch, and finally statements to handle exceptions.
| Code: |
try {
statement(s)
} catch (exceptiontype name) {
statement(s)
} catch (exceptiontype name) {
statement(s)
} finally {
statement(s)
}
|
Some branching statements change the flow of control in a program to a labeled
statement. You label a statement by placing a legal identifier (the label) followed by a colon (
before the statement:
statementName: someJavaStatement;
Use the unlabeled form of the break statement to terminate the innermost switch, for,
while, or do-while statement.
break;
Use the labeled form of the break statement to terminate an outer switch, for, while,
or do-while statement with the given label:
break label;
A continue statement terminates the current iteration of the innermost loop and
evaluates the boolean expression that controls the loop.
continue;
The labeled form of the continue statement terminates the current iteration of the loop
with the given label:
continue label;
Use return to terminate the current method.
return;
You can return a value to the method's caller, by using the form of return that takes a
value.
return value;
by Anatoliy Malyarenko Printer Friendly Page
Send to a Friend
..
Search here again if you need more info!
|