Statement Forms
4.4 The if statement
The simplest way to express conditional execution in Java is by using the if statement, which comes in two forms:
if (condition) statement
if (condition) statement else statement
The condition component of this template is a Boolean-valued expression. The statements can be either simple statements or blocks.
You use the first form of the if statement when your solution strategy calls for a set of statements to be executed only if a particular condition applies. If that condition does not apply, the statements that form the body of the if statement are simply skipped. You use the second form of the if statement for situations in which the program must choose between two independent sets of actions based on the result of a test. The decision is always based on the dynamics of the problem. If the English description of the problem might logically contain the word otherwise, there is a good chance that you’ll need the else form. If the English description conveys no such notion, then the simple i f statement is probably sufficient.
The use of the if statement with the else form is illustrated by the LeapYear program given in Figure 4-1, in which the program needs to print one message if the specified year is a leap year and a different message otherwise. If the problem were instead structured so that a message were printed only in leap years, you would use the simple if form instead, as follows:
if (isLeapYear) {
println(year + " is a leap year."); }
In an if statement, the block of statements executed when the conditional expression is true is called the then clause of the if statement. The block of statements executed when the condition is false—if one is specified—is called the else clause.
The fact that the else clause is optional in the if statement sometimes creates an ambiguity, which is called the dangling-else problem. If you write several if statements nested one within another, some of which have else clauses and some of which don’t, it can be difficult to tell which else goes with which if. When faced with this situation, the Java compiler follows the simple rule that each else clause is paired with the most recent if statement that does not already have an else clause. While this rule is simple for the compiler, it can still be hard for human readers to recognize quickly where each else clause belongs. By adopting a more disciplined programming style than Java requires, it is possible to get rid of dangling-else ambiguities. The following rule governing how to use blocks within if statements eliminates the problem:
If/Else Blocking Rule
For any if statement that (1) requires more than a single line or (2) requires an else clause, always use curly braces to enclose in a separate block the statements under the control of the if statement.
Because this text follows the If/Else Blocking Rule, the if statement appears only in one of the following four forms:
1. A single-line if statement used for extremely short conditions
2. A multiline if statement in which the statements are enclosed in a block
3. An if-else statement that always uses blocks to enclose the statements controlled by the if statement, even if they consist of a single statement
4. A cascadingif statement, used for expressing a series of conditional tests Each of these forms is discussed in more detail in the sections that follow.
Syntax for single-line if statements: if (condition) statement;
where:
condition is the Boolean value being tested
statement is a single statement to be executed if condition is true Syntax for multiline if statements: if (condition) {
statements; }
where:
condition is the Boolean value being tested statements is a block of statements to be
executed if the condition is true Syntax for if-else statements: if (condition) { statementsT } else { statementsF } where:
condition is the Boolean value being tested
statementsT is a block of statements to be
executed if condition is true
statementsF is a block of statements to be
executed if condition is false Syntaxfor cascading ifstatements: if (condition1) { statements1 } else if (condition2) { statements2 } else if (condition3) { statements3 . . . } else { statementsnone } where:
each conditioniis a Boolean expression
each statementsi is a block of statements to
be executed if conditioni is true
statementsnone is the block of statements to
be executed if every conditioni is false
Single-line if statements
The simple one-line format shown in the syntax box to the right is used only for those if statements in which there is no else clause and in which the body is a single statement short enough to fit on the same line as the if. In this type of situation, using braces and extending the if statement from one to three lines would make the program longer and more difficult to read.
Multiline if statements
Whenever the body of an if statement consists of multiple statements or a single statement that is too long for a single line, the statements are enclosed in a block, as shown in the syntax box. In this form, the statements are executed if the condition is true. If the condition is false, the program takes no action at all and continues with the statement following the if.
The if-else statement
To avoid the dangling-else problem, the bodies of if statements that have else clauses are always enclosed within blocks, as shown in the syntax box to the right. Technically, the curly braces that surround the block are necessary only if there is more than one statement governed by that condition. By systematically using those braces, however, you can minimize the possibility of confusion and make your programs easier to maintain.
Cascading if statements
The syntax box on the right illustrates an important special case of the if statement that is useful for applications in which the number of possible cases is larger than two. The characteristic form is that the else part of a condition consists of yet another test to check for an alternative condition. Such statements are called cascading ifstatements and may involve any number of else if lines. For example, the program SignTest in Figure 4-2 uses the cascading if statement to report whether a number is positive, zero, or negative. Note that there is no need to check explicitly for the n< 0 condition. If the program reaches that last else clause, there is no other possibility, since the earlier tests have eliminated the positive and zero cases.
FIGURE 4-2 Program to classify an integer according to its sign
/*
* File: SignTest.java * ---
* This program reads in an integer and classifies it as negative, * zero, or positive depending on its sign.
*/
import acm.program.*;
public class SignTest extends ConsoleProgram { public void run() {
println("This program classifies an integer by its sign."); int n = readInt("Enter n: ");
if (n > 0) {
println("That number is positive."); } else if (n == 0) {
println("That number is zero."); } else {
println("That number is negative."); }
} }
In many situations, the process of choosing among a set of independent cases can be handled more efficiently using the switch statement, which is described in a separate section later in this chapter.
The ?: operator
The Java programming language provides another, more compact mechanism for expressing conditional execution that can be extremely useful in certain situations: the ?: operator. (This operator is referred to as question-mark colon, even though the two characters do not actually appear adjacent to one another.) Unlike any other operator in Java, ?:is written in two parts and requires three operands. The general form of the operation is
condition ? expression1 : expression2
When a Java program encounters the ?: operator, it first evaluates the condition. If the condition turns out to be true, expression1 is evaluated and used as the value of the entire
expression; if the condition is false, the value is the result of evaluating expression2.
The ?: operator is therefore a shorthand form of the if statement if (condition) {
value = expression1;
} else {
value = expression2;
}
where the value of the ?: expression as a whole is whatever would have been stored in value in the expanded, if-statement form.
For example, you can use the ?: operator to assign to max either the value of x or the value of y, whichever is greater, as follows:
max = (x > y) ? x : y;
The parentheses around the condition here are not technically required, but many Java programmers tend to include them in this context to enhance the readability of the code.
One of the most common situations in which the ?: operator makes sense is in calls to println where the output you want differs slightly depending on some condition. For example, suppose that you are writing a program that counts the number of some item and that, after doing all the counting, stores the number of items in the variable nItems. How would you report this value to the user? The obvious way is just to call println using a statement like
println(nItems + " items found.");
But if you are a grammatical purist, you might be a little chagrined to read the output
ItemCount
1 items found.
when nItems happens to have the value 1. You could, however, correct the English by enclosing the println line in the following if statement:
if (nItems == 1) {
println(nItems + " item found."); } else {
println(nItems + " items found."); }
The only problem is that this solution strategy requires a five-line statement to express a relatively simple idea. As an alternative, you could use the ?: operator as follows:
println(nItems + " item" + (nItems == 1 ? "" : "s") + " found."); The string "item" in the output would then be followed by the empty string if nItems is equal to one and the string "s" otherwise. Note that the parentheses are necessary around the expression
(nItems == 1 ? "" : "s")
The ?: operator has relatively low precedence with respect to +, which means that Java would try to do the concatenation first.
In Java, it is possible to overuse the ?: operator. If an essential part of the decision- making structure with a program is hidden away in the ?: operator, those decision- making operations can easily get lost in the rest of the code. On the other hand, if using ?: makes it possible to handle some small detail without writing a complicated i f statement, this operator can simplify the program structure considerably.