switch (args[i])
{
case "-v":
case "-V": System.out.println("Version 1.0");
break;
// ...
default : System.out.println("unknown option");
}
Imagine that a for
statement (discussed shortly) is iterating over each of the arguments in the array of command-line arguments passed to an application’s main()
method. If the argument is -v
(dash and lowercase v) or -V
(dash and uppercase V), the application’s version number will be output. When -v
is specified, it’s necessary to have execution drop through to the following case, which outputs the version number when -V
is specified.
The default case is executed whenever the string referenced by args[i]
doesn’t match any of the case labels. In other words, the user has specified an unknown option.
About loop statements: for, while, and do-while
Loop statements (also known as iteration statements) repeatedly execute other statements for a specific number of iterations (loops), or indefinitely until some terminating condition arises. For example, as previously mentioned, you might want to iterate over all of the String
objects in the array of command-line arguments passed to a main()
method. Java supports the for
, while
, and do-while
iteration statements.
Writing for statements and for loops
The for
statement executes another statement a specific number of times or indefinitely. It is essentially a compact form of the while
statement (discussed later) and has the following syntax:
for ([initialize]; [test]; [update])
statement
This example shows that a for
statement begins with the reserved word for
and continues with a parentheses-delimited and semicolon-separated sequence of three sections:
- initialize: A comma-separated list of variable declarations or assignments. These variables, which are known as iteration variables or loop variables, are used to index arrays, take part in calculations, or perform other tasks.
- test: A Boolean expression that determines how long the loop executes. Execution continues for as long as this expression remains true.
- update: A comma-separated list of expressions that typically modify the loop variables.
Following the for
statement is a statement
to execute repeatedly.
Each of the three sections is optional. As a result, for
can be shrunk down to for (; ;)
. Because there is no stopping condition, the resulting loop is known as an infinite loop.
The following example uses the for
statement to iterate over all elements in an array named args
, outputting the value of each array element:
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
This example works as follows:
- Declare variable
i
and initialize it to0
. - Evaluate
i < args.length
. Ifi
equalsargs.length
, terminate the loop. - Execute
System.out.println(args[i]);
. - Execute
i++
. - Continue with Step 2.
Variable i
is visible to the for
statement’s test
and update
sections, and to statement
. However, it isn’t visible to subsequent statements. If you want subsequent statements to see i
‘s final value, declare i
before for
, as follows:
int i;
for (i = 0; i < args.length; i++)
System.out.println(args[i]);
The variable that controls the loop can be a different primitive type, such as Boolean, character, or double precision floating-point. Here are three examples:
for (boolean b = false; b != true; b = !b)
System.out.println(b); // This statement executes once.
for (char c="A"; c <= 'F'; c++)
System.out.println(c);
for (double d = 0.0; d < 1.0; d += 0.1)
System.out.println(d);
Finally, as previously mentioned, the initialize
section can declare multiple variables. The following example declares two variables, incrementing one variable and decrementing the other variable throughout the loop:
for (int i = 0, j = 5; i <= 5; i++, j--)
System.out.println(i + j);
The output consists of six lines of 5
.
Writing while statements
The while
statement repeatedly executes another statement while its controlling Boolean expression keeps evaluating to true. This statement has the following syntax:
while (Boolean expression)
statement
This syntax shows that a while
statement begins with the reserved word while
and continues with a parenthesized Boolean expression. This statement is followed by another statement to execute repeatedly.
Here’s an example of the while
statement:
int i = 0;
while (i < args.length)
{
System.out.println(args[i]);
i++;
}
This example works as follows:
- Declare variable
i
and initialize it to0
. - Evaluate
i < args.length
. Ifi
equalsargs.length
, terminate the loop. - Execute
System.out.println(args[i]);
. - Execute
i++
. - Continue with Step 2.
This example is the while
equivalent of the previous for
example. You could compact the example to repeatedly execute a simple statement instead of a compound statement, as follows:
int i = 0;
while (i < args.length)
System.out.println(args[i++]);
In this compacted example, we change the postincrement statement to an expression that’s passed to the array index operator. Although the code is more compact, some might prefer the previous example for clarity.
Writing do-while statements
The do-while
statement repeatedly executes a statement while its controlling Boolean expression, which is evaluated after the statement is executed, evaluates to true. This statement has the following syntax:
do
statement
while (Boolean expression); // The semicolon terminator is mandatory.
This syntax shows that a do-while
statement begins with reserved word do
, continues with a statement to execute repeatedly, and ends with the reserved word while
, followed by a parenthesized Boolean expression.
The following example demonstrates the do-while
statement:
int ch;
do
{
System.out.println("Press x to continue.");
ch = System.in.read();
}
while (ch != 'x');
This example works as follows:
- Declare
int
variablech
to store a character’s numeric code. - Prompt the user to press the x key to continue.
- Read a key code from the keyboard via
System.in.read()
, which is a companion ofSystem.out.println()
. Because this method returns the key’s code as anint
, assign this value toch
. - Compare
ch
‘s value with'x'
. Note that'x'
is widened fromchar
toint
before the comparison. Terminate the loop when this expression evaluates to false (ch
equals'x'
). Otherwise, continue with Step 2.
The difference between while
and do-while
is that while
executes its statement zero or more times, whereas do-while
executes its statement one or more times. You will choose either statement based on this property. For example, it’s appropriate to use while
to iterate over the args
array because this array might have zero length and you don’t want to access the array and raise an out-of-bounds exception. In contrast, you would access the array at least once with do-while
. It’s appropriate to use do-while
to prompt the user to enter a key and read the response because these tasks must happen at least once.
Breaking statements
You’ve seen the break
statement used to break out of a switch
statement after a case executed. We can also use break
statements as part of an iteration statement, along with continue
statement. We’ll explore both of these options.
Unlabeled and labeled break statements
The unlabeled break
statement terminates a switch
, for
, while
, or do-while
statement by transferring execution to the first statement following this statement. Here it is by itself:
break;
Here’s an unlabeled break
statement in an iteration statement context:
for (; ;)
{
System.out.println("Press x to continue.");
int ch = System.in.read();
if (ch == 'x')
break;
}
Here we’ve introduced a for
-based infinite loop that repeatedly prompts the user to press the x key and reads this key until it equals 'x'
. An if
statement performs the comparison, executing break;
to terminate the loop when the x key is pressed.
The labeled break statement
This statement terminates a containing and labeled switch
, for
, while
, or do-while
statement by transferring execution to the first statement following the containing statement. It has the following syntax:
break label;
This syntax consists of reserved word break
followed by a non-reserved word identifier to serve as a label, followed by a semicolon. The label must be prefixed to a previous switch
or iteration statement and must be followed by a colon.
The following example demonstrates the labeled break
statement in an iteration statement context:
outer:
while (true)
{
System.out.println("Guess number between 0 and 9.");
while (true)
{
System.out.println("Press n for new game or q to quit.");
int ch = System.in.read();
if (ch == 'n')
break;
if (ch == 'q')
break outer;
}
}
This example presents a pair of nested infinite while
loops that describe part of a number-guessing game. The outer loop is a stub for playing the game, whereas the inner loop prompts the user to play a new game or quit the game.
If the user presses the n key, the unlabeled break
statement is executed to terminate the inner loop so that a new game can be played. If q is pressed, break outer;
is executed to quit the outer loop, which is assigned an outer:
label.
Continue statements
The continue
statements can be labeled or unlabeled. The unlabeled continue
statement skips the remainder of the current iteration and tells the iteration statement to advance to the next iteration. It has the following syntax:
continue;
Here’s an example usage of the unlabeled continue
statement:
for (int i = -2; i <= 2; i++)
if (i == 0)
continue;
else
System.out.println(10 / i);
This example’s for
statement iterates from -2
to 2
, repeatedly executing an if-else
statement and then incrementing i
by 1 after each iteration.
To prevent a divide-by-zero exception when i
contains 0, if
tests i
for 0. If this is the case, it executes continue;
, which causes for
to increment i
and then evaluate i <= 2
. Otherwise, 10 / i
is evaluated and the result is output.
The labeled continue
statement skips the remaining iterations of one or more nested iteration statements and transfers execution to the labeled iteration statement. It has the following syntax:
continue label;
This syntax consists of reserved word continue
followed by a non-reserved word identifier to serve as a label, followed by a semicolon. The label must be prefixed to a previous iteration statement and must be followed by a colon.
Here’s an example using the labeled continue
statement:
outer:
for (int i = -2; i <= 2; i++)
for (int j = -2; j <= 2; j++)
if (i == 0)
continue outer;
else
if (j == 0)
continue;
else
System.out.println(10 / i * j);
This example presents a pair of nested for
loops, with each loop variable ranging from -2 through 2. The idea is to divide 10 by the product of the loop variable values. However, division by zero will occur when either variable contains 0.
To prevent division by zero, a chained if-else
statement is used to test i
‘s and j
‘s values for 0. If i
‘s value is 0, continue outer;
is used to terminate the inner loop and advance the outer loop (with label outer:
) past 0. If j
‘s value is 0, continue;
is used to quit the current inner loop iteration and advance the inner loop past 0. If neither situation arises, the calculation is performed and its result is output.
Empty statements
There is one final statement to consider, which is the empty statement, a statement consisting solely of the semicolon character. This statement accomplishes nothing, and yet it is useful. Consider the following example:
for (int ch; (ch = System.in.read()) != -1; System.out.print((char) ch));
This example copies the contents of the standard input stream, read via calls to System.in.read()
, to the standard output stream, written via calls to System.out.print()
, a companion to System.out.println()
that doesn’t output a line separator. It works best when the standard input stream is redirected from the keyboard to a text file.
When redirected to a file, System.in.read()
returns -1 when there is no more input. When not redirected, System.in.read()
obtains its input from the keyboard and never returns -1. Instead, when there are no more key codes to return, System.in.read()
returns a line separator character — two calls are needed on Windows to return its rn
characters, one call is needed on UnixLinux to return its n
character, and one call is needed on older versions of Mac OS to return its r
character. For more information, check out Newline.
As you can see, all of the work is performed in the for
statement’s initialize
and test
sections. The final semicolon refers to the empty statement, which is executed repeatedly.
Be careful with the empty statement because it can be the source of hard-to-find bugs. For example, you might expect the following for
statement to output 10 instances of the word Hello
:
for (int i = 0; i < 10; i++);
System.out.println("Hello");
Instead, you will only observe a single instance of this word, because of the empty statement after the for
statement’s closing parenthesis. for
executes the empty statement 10 times, after which the method call is executed once.
Example program with Java statements
Now that you’ve learned about Java statements, you can start using them to write interesting Java applications. As an example, I’ve written a game that randomly selects an integer ranging from 0 through 9 and asks you to guess the number. If you guess too high or too low, the game will tell you. It will also tell you when you guess correctly, and it will ask you if you want to play again.
You’ll see several classes and methods in the code:
- I use
System.in.read()
to return either the code of a pressed key (when standard input is not redirected) or an 8-bit value from a file (when standard input is redirected).System.in.read()
is capable of throwing an exception, so I had to append “throws Exception
” to themain()
method header, as inpublic static void main(String[] args) throws Exception
. This prevents the compiler from reporting an error. - To obtain a random integer, I need to invoke the
random()
method member of the standard class library’sMath
class.random()
returns a floating-point value ranging from 0.0 to almost 1.0. An expression converts this number to a more useful integer.
Listing 1 presents the source code for the Guess
application.
Listing 1. Example application using statements in Java
class Guess
{
public static void main(String[] args) throws Exception
{
outer:
while (true)
{
System.out.println("I'm thinking of a number between 0 and 9.");
int number = (int) (Math.random() * 10);
while (true)
{
int guessNumber;
while (true)
{
System.out.println("Enter your guess number between 0 and 9.");
guessNumber = System.in.read();
while (System.in.read() != 'n');
if (guessNumber >= '0' && guessNumber <= '9')
{
guessNumber -= '0';
break;
}
}
if (guessNumber < number)
System.out.println("Your guess is too low.");
else
if (guessNumber > number)
System.out.println("Your guess is too high.");
else
{
System.out.println("Congratulations! You guessed correctly.");
while (true)
{
System.out.println("Press n for new game or q to quit.");
int ch = System.in.read();
while (System.in.read() != 'n');
if (ch == 'n')
continue outer;
if (ch == 'q')
break outer;
}
}
}
}
}
}
Guess
demonstrates many of Java’s fundamental language features, including statements. The main()
method presents a while
statement that generates a new number and gives you a chance to guess it. The expression (int) (Math.random() * 10)
multiplies random()
‘s return value by 10 to change the range to 0.0 to almost 10.0, and converts the result to an integer ranging from 0 through 9.
After generating the number, main()
executes an inner while
statement to handle the guesswork. It repeatedly prompts for a guess, converts the pressed key’s Unicode character value to a binary integer value from 0 through 9, and determines whether the user has guessed correctly or not. A suitable message is output. Users who guess correctly are given the chance to play a new game by pressing n
, or to quit the application by pressing q
.
An interesting part of the source code is while (System.in.read() != 'n');
. I use this statement to flush the line separator character(s) (e.g., rn
on Windows) from the operating system’s keyboard buffer. Without this, you would see multiple prompts because each separator character will be interpreted as an attempt to enter a value from 0 through 9 (or n or q). If you’re running Java on an older version of Mac OS, you’ll probably have to replace n
with r
, which is the Mac’s line separator. No changes are necessary when running on Linux or Unix, whose line separator is n
.
Compile Listing 1 as follows:
javac Guess.java
Then run the application:
java Guess
Below is the output from a sample run:
I'm thinking of a number between 0 and 9.
Enter your guess number between 0 and 9.
5
Your guess is too high.
Enter your guess number between 0 and 9.
2
Your guess is too low.
Enter your guess number between 0 and 9.
3
Your guess is too low.
Enter your guess number between 0 and 9.
4
Congratulations! You guessed correctly.
Press n for new game or q to quit.
q
Note that you could make this code portable by working with the standard class library’s System
class, which offers access to the line.separator
property. This task could be a good exercise for developers who are comfortable with Java’s classes and methods.
Using the Java Shell editor
You might want to create or edit this application using the jshell
utility. You’ll find the /edit
command helpful for this purpose. When you enter /edit, jshell
displays an edit window with Cancel, Accept, and Edit buttons:
- Cancel: Cancel the editor without saving changes.
- Accept: Save changes without leaving the editor. Java Shell displays a modification message at the prompt when changes are saved.
- Exit: Save changes and leave the editor. Java shell displays a modification message at the prompt when changes are saved.
Copy Listing 1 into and exit the editor. Then enter Guess.main(null) at the jshell>
prompt to run the application. When you finish with the application, enter q and you’ll be returned to the jshell>
prompt.
Conclusion
Along with Java expressions and operators, statements are the workhorses of a Java application. Mastering these three basic language features gives you a solid foundation for exploring more advanced aspects of programming with Java. In this article, you’ve learned about Java statements and how to use them in your Java programs.