Section 2.8
Details of Statements

STATEMENTS IN JAVA CAN BE either simple statements or compound statements. Simple statements, such as assignments statements and subroutine call statements, are the basic building blocks of a program. Compound statements, such as while loops and if statements, are used to organize simple statements into complex structures, which are called control structures because they control the order in which the statements are executed. Java has three control structures for doing loops: the while loop, the do loop, and the for loop. It has two control structures for branching: the if statement and the switch statement. This section covers the details of these statements, and it ends with a complete list of all the kinds of statement that can occur in a Java program.

The do Loop

You've already seen the while statement, in which the computer tests a condition at the beginning of the loop, to determine whether it should continue looping:

           while ( boolean-expression )

The do loop is a variation of this in which the test comes at the end. It takes the form:

          while ( boolean-expression );

or, since as usual the statement can be a block,

          do {
          } while ( boolean-expression );

(Note the semicolon, ';', at the end. This semicolon is part of the statement, just as the semicolon at the end of an assignment statement or declaration is part of the statement. More generally, every statement in Java ends either with a semicolon or a right brace, '}'.)

To execute a do loop, the computer first executes the body of the loop -- that is, the statement or statements inside the loop -- and then evaluates the boolean expression. If the value of the expression is true, the computer returns to the beginning of the do loop and repeats the process; if the value is false, it ends the loop and continues with the next part of the program.

The main difference between the do loop and the while loop is that the body of a do loop is executed at least once, before the boolean expression is ever evaluated. In a while loop, if the boolean expression is false when the computer first checks it, then the body of the loop will never be executed at all.

For example, consider the following pseudocode for a game-playing program. The do loop makes sense here instead of a while loop because with the do loop, you know there will be at least one game. Also, the test that is used at the end of the loop wouldn't even make sense at the beginning:

         do {
            Play a Game;
            Ask user if he wants to play another game;
         } while ( the user's response is yes );

The for Loop

The for loop exists to make a common type of while loop easier to write. Many while loops have the same general form:

            while ( continuation-condition ) {

For example, consider

            int years = 0;  // initialize the variable years
            while ( years < 5 ) {   // condition for continuing loop
                interest = principal * rate; // do some statements
                principal += interest;
                years++;   // update the value of the variable years

This loop can be written as the following for statement:

            for ( int years = 0;  years < 5;  years++ ) {
               interest = principal * rate;
               principal += interest;

The initialization, continuation condition, and updating have all been combined in the first line of the for loop. This keeps everything involved in the "control" of the loop in one place, which helps makes the loop easier to read and understand. In general, a for loop takes the form:

            for ( initialization; continuation-condition; update )

or, using a block statement:

            for ( initialization; continuation-condition; update ) {

The continuation-condition must be a boolean-valued expression. The initialization can be any expression, as can the update. Any of the three can be empty. Usually, the initialization is an assignment or a declaration, and the update is an assignment or an increment or decrement operation. The official syntax actually allows the initialization and the update to consist of several expressions, separated by commas. If you declare a variable in the initialization section, the scope of that variable is limited to the for statement; that is, it is no longer valid after the for statement is ended.

Here are a few examples of for statements:

          // print out the alphabet on one line of output
          for ( char ch='A'; ch <= 'Z';  ch++ )
          // count up to 10 and down from 10 at the same time
          for ( int i=0,j=10;  i < 10;  i++,j-- ) {
             TextIO.put(i,5);  // output i in a 5-character wide column
          // compute the number 1 * 2 * 3 * ... * 20
          long factorial = 1;
          for (int num=2; num <= 20; num++)
             factorial *= num;
          System.out.println("20! = " + factorial);

(These examples use TextIO, which was discussed in Section 4. Recall that this is not a built-in part of Java. To use TextIO, you must make the class file TextIO.class available to your program.)

The break and continue Statements

The syntax of the while, do, and for loops allows you to make a test at either the beginning or at the end of the loop to determine whether or not to continue executing the loop. Sometimes, it is more natural to have the test in the middle of the loop, or to have several tests at different places in the same loop. Java provides a general method for breaking out of the middle of any loop. It's called the break statement, which takes the form


When the computer executes a break statement, it will immediately jump out of the loop (or other control structure) that contains the break. It then continues on to whatever follows the loop in the program. Consider for example:

            while (true) {  // looks like it will run forever!
               TextIO.put("Enter a positive number: ");
               N = TextIO.getlnt();
               if (N > 0)   // input is OK; jump out of loop
               TextIO.putln("Your answer must be > 0.");
            // continue here after break

A break statement terminates the loop that immediately encloses the break statement. It is possible to have nested loops, where one loop statement is contained inside another. If you use a break statement inside a nested loop, it will only break out of that loop, not out of the loop that contains the nested loop. There is something called a "labeled break" statement that allows you to specify which loop you want to break. I won't give the details here; you can look them up if you ever need them.

The continue statement is similar to break, but less commonly used. A continue statement tells the computer to skip the rest of the current iteration of the loop. However, instead of jumping out of the loop alltogether, it jumps back to the beginning of the loop and continues with the next iteration (after evaluating the loop's continuation condition to see whether any further iterations are required).

break and continue can be used in while loops, do loops, and for loops. Break can also be used in switch statements, which are covered below. They can be nested inside other statements, such as if statements, within a loop, but in that case they mean to break or continue the loop, not the if statement.

More on the if Statement

I have already discussed the if statement in Section 3. It takes the form

             if (boolean-expression)

As usual, the statements inside an if statements are often blocks. The if statement represents a two-way branch. The else part of an if statement -- consisting of the word "else" and the statement that follows it -- can be omitted.

Now, an if statement is, in particular, a statement. This means that either statement-1 or statement-2 inside an if statement can itself be an if statement. (Note: If statement-1 is an if statement, then it has to have an else part; if it does not, the computer will mistake the "else" of the main if statement for the missing "else" of statement-1. This is called the dangling else problem. You can avoid this problem by enclosing statement-1 between { and }, making it into a block.)

An if statement in which the else part is itself an if statement would look like this (perhaps without the final else part):

             if (boolean-expression-1)
                  if (boolean-expression-2)

However, since the computer doesn't care how a program is laid out on the page, this is usually written in the format:

             if (boolean-expression-1)
             else if (boolean-expression-2)

You should think of this as a single statement representing a three-way branch. When the computer executes this, one and only one of the three statements, statement-1, statement-2, and statement-3, will be executed. The computer starts by evaluating boolean-expression-1. If it is true, the computer executes statement-1 and then jumps all the way to the end of the big if statement, skipping the other two statement's. If boolean-expression-1 is false, the computer skips statement-1 and executes the second, nested if statement. That is, it tests the value of boolean-expression-2 and uses it to decide between statement-2 and statement-3.

Here is an example that will print out one of three different messages, depending on the value of a variable named temperature:

            if (temperature < 50)
               System.out.println("It's cold.");
            else if (temperature < 80)
               System.out.println("It's nice.");
               System.out.println("It's hot.");

If temperature is, say, 42, the computer prints out the message "It's cold", and skips the rest -- without even evaluating the second condition.

You can go on stringing together "else-if's" to make multiway branches with any number of cases:

             if (boolean-expression-1)
             else if (boolean-expression-2)
             else if (boolean-expression-3)
               . // (more cases)
             else if (boolean-expression-N)

You should just remember that only one of the statements will be executed and that the computer will stop evaluating boolean-expressions as soon as it finds one that is true. Also, remember that the final else part can be omitted and that any of the statements can be blocks, consisting of a number of statements enclosed between { and }. (Admittedly, there is lot of syntax here; as you study and practice, you'll become comfortable with it.)

The switch Statement

Java also provides a control structure that is specifically designed to make multiway branches of a certain type: the switch statement. A switch statement allows you to test the value of an expression and, depending on that value, to jump to some location within the switch statement. The positions you can jump to are marked with "case labels" that take the form: "case constant:". This marks the position the computer jumps to when the expression evaluates to the given constant. As the final case in a switch statement you can, optionally, use the label "default:", which provides a default jump point that is used when the value of the expression is not listed in any case label.

A switch statement has the form:

          switch (integer-expression) {
             case integer-constant-1:
             case integer-constant-2:
                .   // (more cases)
             case integer-constant-N:
             default:  // optional default case
          } // end of switch statement

The break statements are technically optional. The effect of a break is to make the computer jump to the end of the switch statement. If you leave out the break statement, the computer will just forge ahead after completing one case and will execute the statements associated with the next case label. This is rarely what you want, but it is legal. (I will note here -- although you won't understand it until you get to the next chapter -- that inside a subroutine, the break statement is sometimes replaced by a return statement.)

Note that you can leave out one of the groups of statements entirely (including the break). You then have two case labels in a row, containing two different constants. This just means that the computer will jump to the same place and perform the same action for each of the two constants.

Here is an example of a switch statement. This is not a useful example, but it should be easy for you to follow. Note, by the way, that the constants in the case labels don't have to be in any particular order, as long as they are all different:

          switch (N) {   // assume N is an integer variable
             case 1:
                System.out.println("The number is 1.");
             case 2:
             case 4:
             case 8:
                System.out.println("The number is 2, 4, or 8.");
                System.out.println("(That's a power of 2.)");
             case 3:
             case 6:
             case 9:
                System.out.println("The number is 3, 6, or 9.");
                System.out.println("(That's a multiple of 3.)");
             case 5:
                System.out.println("The number is 5.");
                System.out.println("The number is 7,");
                System.out.println("   or is outside the range 1 to 9.");

The switch statement is pretty primitive as control structures go, and it's easy to make mistakes when you use it. Java takes all its control structures directly from the older programming languages C and C++. The switch statement is certainly one place where the designers of Java should have introduced some improvements.

The Empty Statement

As a final note in this section, I will mention one more type of statement in Java: the empty statement. This is a statement that consists simply of a semicolon. The existence of the empty statement makes the following legal, even though you would not ordinarily see a semicolon after a }.

             if (x < 0) {
                 x = -x;

The semicolon is legal after the }, but the computer considers it to be an empty statement. Occasionally, you might find yourself using the empty statement when what you mean is, in fact, "do nothing". I prefer, though, to use an empty block, consisting of { and } with nothing between, for such cases.

Occasionally, stray empty statements can cause annoying, hard-to-find errors in a program. For example, the following program segment prints out "Hello" just once, not ten times:

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

Why? Because the ";" at the end of the first line is a statement, and it is this statement that is executed ten times. The System.out.println statement is not really inside the for statement at all, so it is executed just once.

A List of Java Statement Types

I mention the empty statement here mainly for completeness. You've now seen just about every type of Java statement. A complete list is given below for reference. The only new items in the list are the try...catch, throw, and synchronized statements, which are related to advanced aspects of Java known as exception-handling and multithreading. These will be covered in later sections.

Another possible surprise in the list is what I've listed as "other expression statement," which reflects the fact that any expression followed by a semicolon can be used as an expression. To execute such a statement, the computer simply evaluates the expression, and then ignores the value. Of course, this only makes sense when the evaluation has a side effect that makes some change in the state of the computer. An example of this is the expression statement "x++;", which has the side effect of adding 1 to the value of x. Similarly, the function call "TextIO.getln()", which reads a line of input, can be used as a stand-alone statement if you want to read a line of input and discard it. Note that, technically, assignment statements and subroutine call statements are also considered to be expression statements.

Java statement types:

[ Next Section | Previous Section | Chapter Index | Main Index ]