< Zurück | Inhalt | Weiter >

3.2.3 Statements

This section is not intended to be a formal presentation of Java syntactic elements.3 Our purpose here is merely to show you the Java way to express common programming constructs. You will find that these are fundamentally similar to the analogous statements in C and C++. For much more detail on these subjects, see Chapter 3 of Thinking in Java by Bruce Eckel.

Like C, Java has a very small set of statements. Most constructs are actually expressions. Most operations are either assignments or method calls. Those few statements that are not expressions fall into two broad categories:

• Conditional execution statements

• Loop control statements

By the way, you may have already noticed one of the two kinds of comments that Java supports. They are like the C/C++ comments—a pair of slashes (//) marks a comment from there to the end of the line, and a block


image

3. For those so inclined, Sun has a BNF language grammar (http://java.sun.com/docs/ books/jls/second_edition/html/syntax.doc.php) on their Web site, and the Lewis and Loftus book, Appendix L, has a good set of syntax diagrams.


comment consists of everything from the opening /* to the closing */

sequence.


3.2.3.1 Conditional Execution

An experienced programmer probably only needs to see examples of if and other such statements to learn them. It’s only a matter of syntax. Java breaks no new ground here; it adds no new semantics to conditional execution constructs.

The if-else statement. The if can take a single statement without any braces, but we always use the braces as a matter of good style (Example 3.7).


image

Example 3.7 A compound Java if-else statement

if (x < 0) {

y = z + progo;

} else if (x > 5) { y = z + hmron; mylon.grebzob();

} else {

y = z + engrom; mylon.kuggle();

image

}


image




TIP

An important thing to remember about the Java if statement (and all other conditional tests, such as while, do-while, and for) is that, unlike C/C++, its expression needs to evaluate to a boolean. In C/C++, numeric expressions are valid, any nonzero value being considered true, but not so in Java.


The switch statement. For a multiway branch Java, like C/C++, has a switch statement, though the Java version of switch is a bit more restrictive. Example 3.8 shows the syntax.

In Java, the expression in the switch statement must evaluate to either an int or a char. Even short and long are not allowed.

As in C/C++, be sure to put the break statement at the end of each case, or else control will flow right into the next case. Sometimes this is the desired behavior—but if you ever do that deliberately, be sure to add a comment.


image

Example 3.8 A switch statement in Java

switch (rval*k+zval)

{

case 0: mylon.reset(); break;

case 1:

case 4:

// matches either 1 or 4 y = zval+engrom; mylon.kuggle(y);

break; default:

// all other values end up here System.out.println("Unexpected value."); break;

}


image


image

The default case is where control goes when no other case matches the expression. It is optional—you don’t need to have one among your switch cases. Its location is also arbitrary; it could come first, but by convention programmers put it last in the sequence of cases, as a visual “catch all.”



TIP

For whichever case is last (typically default), the ending break is redundant because control will continue outside the break—but we show it here in the example, and use it ourselves in our code. Why? Well, code gets edited—for bug fixes and for feature additions. It is especially important to use break in all the cases in switch statements that have no default case, but even in those that do, we keep the break to avoid forgetting it, should another case ever be added or this last one relocated. We recommend that you do the same.


3.2.3.2 Looping and Related Statements

The while statement. Like the while construct in other computer lan- guages, the expression inside the parentheses is evaluated, and if true, the statement following it is executed. Then the expression is evaluated again, and if still true, the looped statement is again executed. This continues until the expression evaluates to false (Example 3.9).


image

Example 3.9 A Java while statement

while (greble != null)

{

greble.glib();

greble = treempl.morph();

}


image


Technically, the while statement consists of the expression and a single statement, but that single statement can be replaced by a set of statements en- closed in braces (you know, the characters { and }). We will always use braces, even if there is only one statement in our while loop. Experience has shown that it’s a safer practice that leads to code that is easier to maintain. Just treat it as if the braces were required syntax, and you’ll never forget to add them when you add a second statement to a loop.

The do-while loop. To put the terminating check at the bottom of the loop, use do-while as shown in Example 3.10. Notice the need for the terminating semicolon after the expression.


image

Example 3.10 A Java do-while statement

do {


greble.morph();

xrof = treempl.glib();


} while (xrof == null);


image


Die-hard Pascal programmers should note that Java has no repeat-until statement. Sorry. Of course the logic of an until(condition) is equivalent to do-while(!condition).

The for loop. The for loop in Java is very similar to C/C++. It consists of three parts (Example 3.11):

• The initializing expression, done up front before the loop begins

• The conditional expression for terminating the loop


• The expression that gets executed at the end of each loop iteration, just prior to retesting the conditional


image

Example 3.11 A Java for loop

for (i = 0; i < 8; i++) { System.out.println(i);

}


image


Unlike C/C++, Java doesn’t have the comma operator for use within arbi- trary expressions, but the comma is supported as special syntax in Java for loops. It makes it possible to have multiple initializers in the opening of the for loop and multiple expressions in the portion repeated at each iteration of the loop. The result is much the same—you can initialize and increment multiple variables or objects in your for loop.

More formally, the full syntax of the for loop can be described with fol- lowing meta-language as shown in Example 3.12 (where the []* means “zero or more repetitions of”).



image

Example 3.12 Java for loop syntax

for ( before [, before]* ; exit_condition ; each_time [, each_time]* )

statement


image


The biggest difference between C and Java for loops, however, is that Java allows you to declare one or more variables of a single type in the initializing expression of the for loop (Example 3.13). Such a variable’s scope is the for loop itself, so don’t declare a variable there if you want to reference it outside the loop. It is a very handy construct, however, for enumerators, iterators, and simple counters.



image

Example 3.13 A Java for loop with local index

for (int i = 0; i < 8; i++) { System.out.println(i);

}


image


As in the if and while statements, the braces are optional when only a single statement is involved, but good practice compels us always to use the braces. Additional code can easily be added without messing up the logic— should one forget, at that point, the need to add braces.

Speaking of the while loop: When do you use a for and when do you use a while loop? The big advantage of the for loop is its readability. It con- solidates the loop control logic into a single place—within the parentheses. Anyone reading your code can see at once what variable(s) are being used to control how many times the loop executes and what needs to be done on each iteration (e.g., just increment i). If no initialization is needed before starting the loop, or if the increment happens indirectly as part of what goes on in the body of the loop, then you might as well use a while loop. But when the ini- tialization and iteration parts can be clearly spelled out, use the for loop for the sake of the next programmer who might be reading your code.

The for loop with iterators. As of Java 5.0, there is additional syntax for a for loop. It is meant to provide a useful shorthand when looping over the members of an iterator.4 So what’s an iterator? Well, it has to do with collec- tions. Uh, oh, we’re surrounded by undefined terms. One step at a time, here. Java has a whole bunch (we won’t say “collection,” it’s a loaded term) of utility classes that come with it. We mentioned these classes in our discussion of Javadoc. While not part of the language syntax, some of these classes are so useful that you will see them throughout many, if not most, Java programs.

Collection is a generic term (in fact, it’s a Java interface) for several classes that allow you to group similar objects together. It covers such classes as Lists, LinkedLists, Hashtables, Sets, and the like. They are implementations of all those things that you (should have) learned in a Data Structures course in school. Typically you want to add (and sometimes remove) members from a collection, and you may also want to look something up in the collection. (If you’re new to collections, think “array,” as they are a simple and familiar type of collection.) Sometimes, though, you don’t want just one item from the col- lection, but you want to look at all of the objects in the collection, one at a time. The generic way to do that, the way that hides the specifics of what kind of collection you have (linked list, or array, or map) is called an iterator.5


image

4. This feature is related to the topic of templates and generics. See Section 3.5.

5. The earliest versions of Java used an object called an Enumeration. It does much the same thing as an iterator, but with somewhat clumsier method names. Iterators also allow for a


The purpose of an iterator, then, is to step through a collection one item at a time. Example 3.14 shows a collection being built from the arguments on the command line. Then two iterators are used to step through the collection


image

Example 3.14 Using iterators

import java.util.*;


public class Iter8

{

public static void main(String [] args)

{

// create a new (empty) ArrayList ArrayList al = new ArrayList();


// fill the ArrayList with args for(int i = 0; i < args.length; i++) {

al.add(args[i]);

}


// use the iterator in the while loop Iterator itr1 = al.iterator();


while(itr1.hasNext()) { String onearg;

onearg = (String) (itr1.next()); System.out.println("arg=" + onearg);

}


// define and use the iterator in the for loop: for(Iterator itr2 = al.iterator(); itr2.hasNext(); ) {

String onearg;

onearg = (String) (itr2.next()); System.out.println("arg=" + onearg);

}


} // main


} // Iter8


image


image

remove() method, something that Enumeration doesn’t support. The Enumeration class is still around, but less frequently used. It is only available from certain older utility classes.


and print the objects in the collection to the command window. The first iter- ator uses the while loop, the second one uses a for loop, but they both do the same thing.

As of Java 5.0, there is another way to work your way through a collection, one that requires less type casting, but more importantly one that can enforce the type of objects at compile time.

Notice in Example 3.14 that the result of the next() is coerced into type String. That’s because everything coming from the iterator (via the next() method) comes to us as a generic object. That way an iterator can handle any type of object, but that also means that it is up to the application program to know what type should be coming back from the iterator. Any typecasting error won’t be found until runtime.

With the syntax added in 5.0, not only is there a shorthand in the for loop for looping with an iterator. There is also syntax to tell the compiler explic- itly what type of objects you are putting into your collection or array so that the compiler can enforce that type.

Example 3.15 may help to make this clearer.


image

Example 3.15 Using a for loop iterator

import java.util.*;


public class Foreign

{

public static void main(String [] args)

{

List <String> loa = Arrays.asList(args); System.out.println("size=" + loa.size());

for(String str : loa) { System.out.println("arg=" + str);

}


} // main

} // Foreign


image


Here we build a List from the arguments supplied on the command line. Notice the type name inside of angle brackets (less-than and greater-than signs).


This is the new syntax that tells the compiler that we are putting Strings into the List. The compiler will enforce that and give a compile time error if we try to add any other type to the List.

Now we come to the for loop. Read it as “for str in loa” or “for String values of str iterating over loa.” We will get an iterator working out of sight that will iterate over the values of loa, our List. The values (the result of the next() method) will be put in the String variable str. So we can use str inside the body of the loop, with it taking on successive values from the collection.

Let’s describe the syntax, then, as


for ( SomeType variable : SomeCollectionVariable ) {

}


which will define variable to be of type SomeType and then iterate over the SomeCollectionVariable. Each iteration will execute the body of the loop, with the variable set to the next() value from the iterator. If the collection is empty, the body of the loop will not be executed.

This variation of the for loop works for arrays as well as for these new typed collections. The syntax for arrays is the same. Example 3.16 will echo the arguments on the command line, but without loading up a List like we did in our previous example.



image

Example 3.16 A for loop iterator for arrays

import java.util.*;


public class Forn

{

public static void main(String [] args)

{

for(String str : args) { System.out.println("arg="+str);

}


} // main

} // Forn


image


The break and continue statements. There are two statements that will change the course of execution of the while, do-while, and for loops from within the loop. A continue will cause execution to skip the rest of the body of the loop and go on to the next iteration. With a for loop, this means execut- ing the iteration expression, and then executing the test-for-termination expres- sion. With the while and do-while loops, this means just going to the test expression.

You can quit out of the loop entirely with the break statement. Execution continues on the next statement after the loop.


3.2.3.3 The return statement

There is one more statement that we need to cover. The return statement is optionally followed by an expression. Execution of the current method ends at once upon executing return, and the expression is used as the return value of the method. Obviously, the type of the expression must match the return type of the method. If the method is void, there should be no return expression.