Checking for Unperformed Side Effects
Be wary of short-circuit behavior on the exam, as questions are known to alter a variable on the right side of the expression that may never be reached. This is referred to as an unperformed side effect. For example, what is the output of the following code?
int rabbit = 6; boolean bunny = (rabbit>= 6) || (++rabbit <= 7); System.out.println(rabbit);
Because rabbit >= 6
is true
, the increment operator on the right side of the expression is never evaluated, so the output is 6
.
Making Decisions with the Ternary Operator
The final operator you should be familiar with for the exam is the conditional operator, ? :
, otherwise known as the ternary operator. It is notable in that it is the only operator that takes three operands. The ternary operator has the following form:
booleanExpression ? expression1 : expression2
The first operand must be a boolean
expression, and the second and third operands can be any expression that returns a value. The ternary operation is really a condensed form of a combined if
and else
statement that returns a value. We cover if
/else
statements in a lot more detail in Chapter 3, so for now we just use simple examples.
For example, consider the following code snippet that calculates the food amount for an owl:
int owl = 5; int food; if(owl < 2) { food = 3; } else { food = 4; } System.out.println(food); // 4
Compare the previous code snippet with the following ternary operator code snippet:
int owl = 5; int food = owl < 2 ? 3 : 4; System.out.println(food); // 4
These two code snippets are equivalent. Note that it is often helpful for readability to add parentheses around the expressions in ternary operations, although doing so is certainly not required. It is especially helpful when multiple ternary operators are used together, though. Consider the following two equivalent expressions:
int food1 = owl < 4 ? owl > 2 ? 3 : 4 : 5; int food2 = (owl < 4 ? ((owl > 2) ? 3 : 4) : 5);
While they are equivalent, we find the second statement far more readable. That said, it is possible the exam could use multiple ternary operators in a single line.
For the exam, you should know that there is no requirement that second and third expressions in ternary operations have the same data types, although it does come into play when combined with the assignment operator. Compare the two statements following the variable declaration:
int stripes = 7; System.out.print((stripes > 5) ? 21 : "Zebra"); int animal = (stripes < 9) ? 3 : "Horse"; // DOES NOT COMPILE
Both expressions evaluate similar boolean
values and return an int
and a String
, although only the first one will compile. System.out.print()
does not care that the expressions are completely different types, because it can convert both to Object
values and call toString()
on them. On the other hand, the compiler does know that "Horse"
is of the wrong data type and cannot be assigned to an int
; therefore, it does not allow the code to be compiled.
Ternary Expression and Unperformed Side Effects
As we saw with the conditional operators, a ternary expression can contain an unperformed side effect, as only one of the expressions on the right side will be evaluated at runtime. Let's illustrate this principle with the following example:
int sheep = 1; int zzz = 1; int sleep = zzz<10 ? sheep++ : zzz++; System.out.print(sheep + "," + zzz); // 2,1
Notice that since the left-hand boolean
expression was true
, only sheep
was incremented. Contrast the preceding example with the following modification:
int sheep = 1; int zzz = 1; int sleep = sheep>=10 ? sheep++ : zzz++; System.out.print(sheep + "," + zzz); // 1,2
Now that the left-hand boolean
expression evaluates to false
, only zzz
is incremented. In this manner, we see how the changes in a ternary operator may not be applied if the particular expression is not used.
For the exam, be wary of any question that includes a ternary expression in which a variable is modified in one of the expressions on the right-hand side.
Summary
This chapter covered a wide variety of Java operator topics for unary, binary, and ternary operators. Hopefully, most of these operators were review for you. If not, you need to study them in detail. It is important that you understand how to use all of the required Java operators covered in this chapter and know how operator precedence and parentheses influence the way a particular expression is interpreted.
There will likely be numerous questions on the exam that appear to test one thing, such as NIO.2 or exception handling, when in fact the answer is related to the misuse of a particular operator that causes the application to fail to compile. When you see an operator involving numbers on the exam, always check that the appropriate data types are used and that they match each other where applicable.
Operators are used throughout the exam, in nearly every code sample, so the better you understand this chapter, the more prepared you will be for the exam.
Exam Essentials
Be able to write code that uses Java operators. This chapter covered a wide variety of operator symbols. Go back and review them several times so that you are familiar with them throughout the rest of the book.
Be able to recognize which operators are associated with which data types. Some operators may be applied only to numeric primitives, some only to boolean
values, and some only to objects. It is important that you notice when an operator and operand(s) are mismatched, as this issue is likely to come up in a couple of exam questions.
Understand when casting is required or numeric promotion occurs. Whenever you mix operands of two different data types, the compiler needs to decide how to handle the resulting data type. When you're converting from a smaller to a larger data type, numeric promotion is automatically applied. When you're converting from a larger to a smaller data type, casting is required.
Understand Java operator precedence. Most Java operators you'll work with are binary, but the number of expressions is often greater than two. Therefore, you must understand the order in which Java will evaluate each operator symbol.
Be able to write code that uses parentheses to override operator precedence. You can use parentheses in your code to manually change the order of precedence.
Review Questions
The answers to the chapter review questions can be found in the Appendix.
1 Which of the following Java operators can be used with boolean variables? (Choose all that apply.)==+--!%~Cast with (boolean)
2 What data type (or types) will allow the following code snippet to compile? (Choose all that apply.)byte apples = 5; short oranges = 10; _____ bananas = apples + oranges;intlongbooleandoubleshortbyte
3 What change, when applied independently, would allow the following code snippet to compile? (Choose all that apply.)3: