The following table lists the statements supported by Java (and by C++
with some exceptions) for controlling the logical flow of the program.
Statement Type if-else selection switch-case selection for loop while loop do-while loop try-catch-finally exception handling throw exception handling break miscellaneous continue miscellaneous label: miscellaneous return miscellaneous goto reserved by Java but not supported |
| Note that the operation of the input/output system for Java is significantly different from that for C++ so the conditional expression which involved the I/O system was also different between the two. |
while (conditional expression) statement or compound statement; |
The following while statement was extracted from a previous Java
program.
while( (ch1 = System.in.read() ) != '#') ch2 = ch1; |
The while statement that follows was extracted from a previous
C++ program.
|
| The C++ statement is fairly straightforward in that the conditional expression simply calls one of the standard I/O functions which returns a character from the standard input device. |
The System class defines a class variable named in. Since it is a class variable, it can be accessed using the name of the System class without the requirement to instantiate an object of the System class.
The in variable is an instance of a class that provides a read() method which returns a character from the standard input device. Therefore, the expression System.in.read() constitutes a call to the read method of the object referred to by the in variable of the System class.
Note that the while statement is used to form an entry condition loop in both Java and C++. The significance of an entry condition loop is that the conditional expression is tested before the statements in the loop are executed. If it tests false initially, the statements in the loop will not be executed.
if(conditional expression) statement or compound statement; else //optional statement or compound statement; //optional |
switch(expression){
case constant:
//sequence of optional statements
break; //optional
case constant:
//sequence of optional statements
break; //optional
.
.
.
default //optional
//sequence of optional statements
}
|
Execution of statements continues until the optional break is
encountered. When break is encountered, execution of the switch
statement is terminated and control is passed to the next statement following
the switch statement.
| Also in C++, the expression must evaluate to an integer. This
integer is tested against a series of integer or character
constants. If a match is found, the sequence of optional statements is
executed. Execution of statements continues until the optional break
is encountered. When break is encountered, execution of the switch
statement is terminated and control is passed to the next statement following
the switch statement.
Note that character matches are possible in C++ because the char type is C++ is really an 8-bit integer type. That is not the case in Java. |
If no match is found and the optional default keyword along with a sequence of optional statements has been provided, those statements will be executed.
Java also supports labeled break statements. This capability can be used to cause Java to exhibit different behavior when switch statements are nested. This will be explained more fully in a later section on labeled break statements.
The heart of a for loop in both Java and C++ consists of three
clauses separated by semicolons as shown below.
for (first clause; second clause; third clause) single or compound statement |
In both Java and C++, the comma operator guarantees that its
left operand will be executed before its right operand.
| While the comma operator has other uses in C++, this is the only use of the comma operator in Java. |
Note that variables can also be declared and initialized in the first clause, and this has an interesting ramification regarding scope which will be discussed later.
The second clause in both Java and C++ consists of a single expression
which must eventually evaluate to false to cause the loop to terminate.
| Since any expression which evaluates to zero is treated as false in C++, the range of possible expressions that can be used in the second clause in C++ is limitless. |
Typically relational expressions or relational and conditional expressions are used in the second clause.
The value of the second clause is tested when the statement first
begins execution, and at the beginning of each iteration thereafter.
Therefore, the for loop is an entry condition loop.
| Although the third clause appears physically at the top of the loop, it isn't executed until the statements in the body of the loop have completed execution. |
Multiple expressions can appear in the third clause, separated by the comma operator. Again, those expressions will be executed from left to right. If variables are updated in the third clause and used in the body of the loop, it is important to understand that they do not get updated until the execution of the body is completed.
As mentioned earlier, it is also allowable to declare variables in the
first clause of a for loop.
The most up-to-date versions of C++ compilers allow declaration of
loop control variables inside the for loop having the same name
as variables declared outside the loop. The scope of those variables declared
inside the loop is limited to the loop. This is illustrated by the following
C++ program which declares a local method variable named cnt and
then declares a loop control variable named cnt. The values of the
two variables having the same name are displayed at several points in the
program. The output produced by this program is shown in the comments at
the beginning of the program.
The Java compiler, version JDK 1.1.3 treats variables declared inside the first clause of a for loop differently from the way they are treated in C++. The above C++ program declared a variable named cnt at two different places in the program, once outside the for loop and once inside the first clause of the for loop. However, that doesn't work in Java. |
If you declare it outside the for loop, you can access it either outside or inside the loop.
However, if you declare it inside the loop, you can access it only inside the loop. In other words, the scope of variables declared inside a for loop is limited to the loop.
This is illustrated in following sequence of four simple programs.
The following Java program refuses to compile with a complaint that
a variable named cnt has already been declared in the method when
the attempt is made to declare it in the for loop.
/*File for1.java Copyright 1997, R.G.Baldwin
This program will not compile because the variable named
cnt is declared twice.
**********************************************************/
class for1 { //define the controlling class
public static void main(String[] args){ //main method
int cnt = 5; //declare local method variable
System.out.println(
"Value of method var named cnt is " + cnt);
for(int cnt = 0; cnt < 2; cnt++)
System.out.println(
"Value of loop var named cnt is " + cnt);
System.out.println(
"Value of method var named cnt is " + cnt);
}//end main
}//End controlling class. Note no semicolon required
|
However, this program refused to compile because an attempt was made
to access the variable named cnt outside the for loop. This
was not allowed because the variable was declared inside the for
loop and the scope of the variable was limited to the loop.
/*File for2.java Copyright 1997, R.G.Baldwin
This program will not compile because the variable declared
inside the for loop is not accessible outside the loop.
**********************************************************/
class for2 { //define the controlling class
public static void main(String[] args){ //main method
for(int cnt = 0; cnt < 2; cnt++)
System.out.println(
"Value of loop var named cnt is " + cnt);
System.out.println(
"Value of method var named cnt is " + cnt);
}//end main
}//End controlling class. Note no semicolon required
|
/*File for3.java Copyright 1997, R.G.Baldwin
This program will compile because the variable declared
inside the for loop is accessed only inside the loop.
**********************************************************/
class for3 { //define the controlling class
public static void main(String[] args){ //main method
for(int cnt = 0; cnt < 2; cnt++)
System.out.println(
"Value of loop var named cnt is " + cnt);
}//end main
}//End controlling class.
|
/*File for4.java Copyright 1997, R.G.Baldwin
This program will compile and run because the variable
named cnt is declared outside the for loop and is not
declared inside the for loop.
**********************************************************/
class for4 { //define the controlling class
public static void main(String[] args){ //main method
int cnt = 5; //declare local method variable
System.out.println(
"Value of method var named cnt is " + cnt);
for(cnt = 0; cnt < 2; cnt++)
System.out.println(
"Value of loop var named cnt is " + cnt);
System.out.println(
"Value of method var named cnt is " + cnt);
}//end main
}//End controlling class. Note no semicolon required
|
One author suggests that even the middle clause can be empty, but it isn't obvious to this author how the loop would ever terminate if there is no conditional expression to be evaluated. Perhaps the loop could be terminated by using a break inside the loop, but in that case, you might just as well use a while loop.
do {
statements
} while (conditional expression);
|
Other than the differences resulting from the availability of labeledbreak and continue statements in Java, and the difference in the way that Java and C++ determine true and false, there is essentially no difference in the behavior of the do-while loop in Java and C++.
Although some authors suggest that this provides an alternative to the infamous goto statement (which is still supported by C++ but is not supported by Java), it appears that the behavior of the labeledbreak and labeled continue statements is much more restrictive than a general goto.
In particular, it appears that a labeled break or continue will compile successfully only if the labeled statement is a statement which would normally be referenced by an unlabeled break or continue.
The break statement can be used either in a switch statement or in a loop. When encountered in a switch statement, break causes control to be passed to the next statement outside the innermost enclosing switch statement.
When break is encountered in a loop, it causes control to be passed to the next statement outside the innermost enclosing loop.
As we will see later, labeled break statements can be used to pass control to the next statement following switch or loop statements beyond the innermost switch or loop statement when those statements are nested.
The continue statement cannot be used in a switch statement, but is confined to loops.
When an unlabeled continue statement is encountered in either Java or C++, it causes the current iteration to be terminated and the next iteration to begin.
A labeled continue statement can cause control to be passed to the next iteration of an outer enclosing loop in a nested loop situation.
An example of the use of an unlabeled switch statement is given in the next section.
To begin with, the syntax of a labeled statement is the same
in Java or C++: a label followed by a colon ahead of the statement.
The label can be any legal Java or C++ identifier. This syntax is illustrated
in the following example.
myLabel: myStatement;/td> |
After reviewing switch1.java, consider the same program modified
to use a labeled break which is named switch2.java.
The outputs from both programs are shown in the comments at the beginning
of the program. By examining the second program, and comparing the output
from the second program with the first program, you should be able to see
how the use of the labeled break statement causes control to break
all the way out of the labeled switch statement.
/*File switch1.java
This is a Java application which serves as a baseline
comparison for switch2.java which uses a labeled break.
Note that the program uses nested switch statements.
The program displays the following output:
Match and break from here
Case 6 in outer switch
Default in outer switch
Beyond switch statements
********************************************************/
class switch1 { //define the controlling class
public static void main(String[] args){ //main method
//Note that the following labeled switch statement is
// not referenced by a labeled break in this program.
// It will be referenced in the next program.
outerSwitch: switch(5){//labeled outer switch statement
case 5: //execute the following switch statement
//Note that the code for this case is not followed
// by break. Therefore, execution will fall through
// the case 6 and the default.
switch(1){ //inner switch statement
case 1: System.out.println(
"Match and break from here");
break; //break with no label
case 2: System.out.println(
"No match for this constant");
break;
}//end inner switch statement
case 6: System.out.println("Case 6 in outer switch");
default: System.out.println(
"Default in outer switch");
}//end outer switch statement
System.out.println("Beyond switch statements");
}//end main
}//End switch1 class.
|
/*File switch2.java
This is a Java application which uses a labeled break.
Note that the program uses nested switch statements.
See switch1.java for a comparison program which does not
use a labeled break.
The program displays the following output:
Match and break from here
Beyond switch statements
**********************************************************/
class switch2 { //define the controlling class
public static void main(String[] args){ //main method
outerSwitch: switch(5){//labeled outer switch statement
case 5: //execute the following switch statement
//Note that the code for this case is not followed by
// break. Therefore, except for the labeled break at
// case 1, execution would fall through the case 6 and
// the default as demonstrated in the program named
// switch1. However, the use of the labeled break
// causes control to break all the way out of the
// labeled switch bypassing case 6 and the default.
switch(1){ //inner switch statement
case 1: System.out.println(
"Match and break from here");
break outerSwitch; //break with label
case 2: System.out.println(
"No match for this constant");
break;
}//end inner switch statement
case 6: System.out.println(
"Case 6 in outer switch");
default: System.out.println("Default in outer switch");
}//end outer switch statement
System.out.println("Beyond switch statements");
}//end main
}//End switch1 class.
|
break outerSwitch; //break with label |
Again, it will be left as an exercise for the student to demonstrate this behavior to his or her satisfaction.
Pascal programmers will recall that it is possible to return a value from a Pascal function but the keyword return is not part of the Pascal language. Rather, in order to return a value from a Pascal function, a statement is executed which appears to be assigning the value to an identifier which matches the name of the function.
The type of value returned in C++ and Java must match the type of the
declared return value for the method or function. If the return value is
declared as void, you can use the following syntax to terminate
the function. (You can also simply allow the method or function to run
out of statements to execute.)
return; |
return x+y; |
| C++ allows you to return by value, pointer, or reference.
Care must be exercised when returning by pointer or reference
in C++ to ensure that the object being referred to will continue to exist
after the function terminates. For example, returning a pointer or a reference
to a local automatic variable in a function can lead to problems
since the variable will cease to exist as soon as the function terminates.
The Borland C++ compilers used by this author will not permit you to
return a reference to an automatic local variable but they will
allow you to return a pointer to such a variable. This is illustrated in
the following simple C++ program which returns a pointer to a local variable,
creates an array in the main function to modify memory, and then uses the
returned pointer to display the contents of the pointed-to memory. The
program displays garbage because after the function terminates, the
pointer points to a memory address which is no longer valid. This is
one of the pitfalls that Java is designed to eliminate.
|
In the case of objects, returning by value returns a copy of the address where the object is stored.
Note that having a copy of the address is just as good as having the original address. All objects in Java are stored in dynamic memory and that memory is not overwritten until all references to that memory cease to exist.
This is illustrated in the following Java application which
Note that this program also illustrates the need to instantiate an object
of the controlling class in order to allow its (non-class) methods to be
called by code in main(). This is because main is static
and code in static methods can only access other static methods.
The test method used in this program is not static.
/*File return2.java Copyright 1997, R.G.Baldwin
This is a Java application program which illustrates
returning a reference to an object from a method.
The program also illustrates instantiating an object of
the controlling class to allow its methods to be called.
The output from this program is as shown below:
Return value is 6
**********************************************************/
class return2 { //define the controlling class
public static void main(String[] args){ //main method
//Instantiate an object of the controlling class to
// allow its methods to be called.
return2 obj = new return2();
//Declare a reference to an object of the type which
// will be returned from the test() method.
myClass mainObj;
//Use the object of the controlling class to call the
// test() method and assign the returned reference to
// mainObj.
mainObj = obj.test();
//Attempt to overwrite the returned object by creating
// a very large array and filling it with data.
int[] memEater = new int[2000000];
for(int i = 0; i < 2000000; i++) memEater[i] = i + 5;
//Display the value in the object returned by test()
// to show that the reference is still valid.
System.out.println("Return value is "
+ mainObj.myData );
}//end main
//this is a method of the controlling class
myClass test(){
//instantiate a local object
myClass localObj = new myClass(6);
//return reference to the local object
return localObj;
}//end test method
}//End controlling class.
class myClass{//class used to instantiate object in test()
int myData;
myClass(int inData){myData = inData;}//constructor
} //end myClass
|
In this case, the reference is assigned to and saved in a reference
variable which is a local variable in the calling method, main()
so that it doesn't cease to exist.
| The following C++ program provides behavior similar to the Java program.
In this program, rather than declaring an automatic variable in
the function, code in the function creates an automatic pointer
variable in the function and also creates a variable in dynamic memory.
The address of that variable in dynamic memory is assigned to the automatic
pointer variable in the function.
Although the automatic pointer variable in the function is destroyed when the function terminates, the variable in dynamic memory is not destroyed in this case until the program terminates (no calls were made to the delete operator). A copy of the automatic pointer variable is returned from the function and assigned to a pointer variable in the calling function, which continues to point to valid data in memory even after the function terminates. This is one way to cause a function in C++ to instantiate an object
and pass it back to the calling function while maintaining its validity
after the function terminates.
|
Suffice it at this point to say that whenever an exception is detected, control is transferred to an exception event handler if such an event handler has been provided. Otherwise, the program will terminate. Thus, the exception handling system should be mentioned in discussions regarding flow of control.
A - The following table lists the
statements supported by Java for controlling the logical flow of the program.
Statement Type if-else selection switch-case selection for loop while loop do-while loop try-catch-finally exception handling throw exception handling break miscellaneous continue miscellaneous label: miscellaneous return miscellaneous goto reserved by Java but not supported |
A - The general syntax of a while
statement follows :
while (conditional expression) statement or compound statement; |
A - True.
Q - A while loop in Java is an entry condition loop: True or False? If false, explain why.
A - True. The while statement is used to form an entry condition loop in Java.
Q - What is the significance of an entry condition loop?
A - The significance of an entry condition loop is that the conditional expression is tested before the statements in the loop are executed. If it tests false initially, the statements in the loop will not be executed.
Q - Provide pseudo-code illustrating the general syntax of the if else statement in Java.
A - The general syntax of the ifelse
statement
in Java is:
if(conditional expression) statement or compound statement; else //optional statement or compound statement; //optional |
A - The general syntax of the switch-case
statement follows:
switch(expression){
case constant:
sequence of optional statements
break; //optional
case constant:
sequence of optional statements
break; //optional
.
.
.
default //optional
sequence of optional statements
}
|
A - The pseudo-code fragment follows:
switch(expression){
case constant:
sequence of optional statements
break; //optional
case constant:
sequence of optional statements
break; //optional
.
.
.
default //optional
sequence of optional statements
}
|
If no match is found and the optional default keyword along with a sequence of optional statements has been provided, those statements will be executed.
Q - What are the three actions normally involved in the operation of a loop (in addition to executing the code in the body of the loop)?
A - The operation of a loop normally involves the following three actions in addition to executing the code in the body of the loop:
A - False: The heart of a for loop consists of three clauses separated by semicolons, not colons.
Q - Provide pseudo-code illustrating the general syntax of a for loop in Java.
A - The general syntax of a for
loop in Java is shown below.
for (first clause; second clause; third clause) single or compound statement |
A - True. The first and third clauses can consist of one or more expressions, separated by the comma operator.
Q - What is the guarantee made by the comma operator?
A - The comma operator guarantees that its left operand will be executed before its right operand.
Q - The expressions within the first clause in the parentheses in a for loop can be executed only once during each iteration of the loop: True or False? If false, explain why.
A - False. The expressions in the first clause may be executed only once, at the beginning of the loop, regardless of the number of iterations.
Q - While any legal expression(s) may be contained in the first clause within the parentheses of a for loop, the first clause has a specific purpose. What is that purpose?
A - Any legal expression(s) may be contained in the first clause of a for loop, but typically the first clause is used for initialization. The purpose of the first clause is initialization.
Q - Variables can be declared and initialized within the first clause in the parentheses of a for loop? True or False. If false, explain why.
A - True. Variables can be declared and initialized in the first clause of a for loop.
Q - The second clause in the parentheses of a for loop consists of a single expression which must eventually evaluate to true to cause the loop to terminate: True or False? If false, explain why.
A - False. The second clause consists of a single expression which must eventually evaluate to false (not true) to cause the loop to terminate.
Q - A for loop is an exit condition loop: True or False? If false, explain why.
A - False. The value of the second clause is tested when the statement first begins execution, and at the beginning of each iteration thereafter. Therefore, the for loop is an entry condition loop.
Q - Because a for loop is an entry condition loop, the third clause inside the parentheses is executed at the beginning of each iteration: True or False? If false, explain why.
A - False. Although the third clause appears physically at the top of the loop, it isn't executed until the statements in the body of the loop have completed execution. This is an important point since this clause is typically used to update the control variable, and perhaps other variables as well. If variables are updated in the third clause and used in the body of the loop, it is important to understand that they do not get updated until the execution of the body is completed.
Q - A return statement is used to terminate a method and (optionally) return a value to the calling method: True or False? If False, explain why.
A - True. Java supports the use of the return statement to terminate a method and (optionally) return a value to the calling method or function.
Q - Exception handling modifies the flow of control of a Java program: True or False. If false, explain why.
A - True. Exception handling is a process which modifies the flow of control of a program.