The Nuts and Bolts of the Java Language |
ThecountChars
method uses several operators including=
,!=
,++
, and+
, which are highlighted in this listing:Operators perform some function on either one or two operands or three operands. Operators that require one operand are called unary operators. For example,import java.io.*; public class Count { public static void countChars(Reader in) throws IOException { int count = 0; while (in.read() != -1) count++; System.out.println("Counted " + count + " chars."); } // ... main method omitted ... }++
is a unary operator that increments the value of its operand by 1. Operators that require two operands are binary operators. For example,=
is a binary operator that assigns the value from its right-hand operand to its left-hand operand. And finally tertiary operators are those that require three operands. The Java language has one tertiary operator,?:
, which is a short-handif
-else
statement.Java's unary operators can use either prefix or postfix notation. Prefix notation means that the operator appears before its operand:
Postfix notation means that the operator appears after its operand:operator opAll of Java's binary operators use infix notation, which means that the operator appears between its operands:op operatorJava's only tertiary operator is also infix; each component of the operator appears between operands:op1 operator op2In addition to performing the operation, an operator also returns a value. The value and its type depends on the operator and the type of its operands. For example, the arithmetic operators, which perform basic arithmetic operations such as addition and subtraction, return numbers-the result of the arithmetic operation. The data type returned by the arithmetic operators depends on the type of its operands: If you add two integers, you get an integer back. An operation is said to evaluate to its result.expr ? op1 : op2It's useful to divide Java's operators into these categories: arithmetic, relational and conditional, bitwise and logical, and assignment. These are discussed in the following sections.
Arithmetic Operators
The Java language supports various arithmetic operators for all floating-point and integer numbers. These include+
(addition),-
(subtraction),*
(multiplication),/
(division), and%
(modulo). For example, you can use this Java code to add two numbers:Or you can use the following Java code to compute the remainder that results from dividingaddThis + toThisdivideThis
bybyThis
:divideThis % byThisThis table summarizes Java's binary arithmetic operations:
Operator Use Description +
op1 + op2
Adds op1 and op2 -
op1 - op2
Subtracts op2 from op1 *
op1 * op2
Multiplies op1 by op2 /
op1 / op2
Divides op1 by op2 %
op1 % op2
Computes the remainder of dividing op1 by op2
Note: The Java language extends the definition of the+
operator to include string concatenation. ThecountChars
method uses+
to concatenate "Counted
", the value ofcount
, and "chars.
", as shown here:This operation automatically coerces the valueSystem.out.println("Counted " + count + " chars.");count
to aString
. You'll see more about this in Arrays and Strings.
The
+
and-
operators have unary versions that perform the following operations:
Operator Use Description +
+op
Promotes +
toint
if it's abyte
,short
, orchar
-
-op
Arithmetically negates op
There also are two short cut arithmetic operators,
++
which increments its operand by 1, and--
which decrements its operand by 1. ThecountChars
method uses++
to increment thecount
variable each time it reads a character from the input source with this statement:Note that thecount++;++
operator appears after its operand in this example. This is the postfix version of the operator.++
also has a prefix version in which++
appears before its operand. Both the prefix and postfix versions of this operator increment the operand by 1. So why are there two different versions? Because each version evaluates a different value:op++
evaluates to the value of the operand before the increment operation, and++op
evaluates the value of the operand after the increment operation.In the
countChars
method, suppose thatcount
is say, 5, before the following statement is executed:After the statement is executed the value ofcount++;count
is 6. No surprises there. However, the statementcount++
evaluates to 5. In the same scenario the prefix version of++
would also setcount
to 6. However the statement++count
does not evaluate to 5 like the postfix version of++
does; rather, it evaluates to 6:This difference is unimportant in++count;countChars
but is critical in situations where the value of the statement is used in the middle of a more complex computation, for flow control, or for something else. For example, the following loop will execute one less time if you changecount++
to++count
:do { . . . } while (count++ < 6);Similarly,
--
also has prefix and postfix versions, which function in the same way as++
. The operations of these operators are summarized in the following table:
Operator Use Description ++
op++
Increments op
by 1; evaluates to value before incrementing++
++op
Increments op
by 1; evaluates to value after incrementing--
op--
Decrements op
by 1; evaluates to value before decrementing--
--op
Decrements op
by 1; evaluates to value after decrementing
Relational and Conditional Operators
A relational operator compares two values and determines the relationship between them. For example,!=
returnstrue
if the two operands are unequal. ThecountChars
method uses!=
to determine whether the value returned byin.read
is not equal to-1
. This table summarizes Java's relational operators:
Operator Use Return true
if>
op1 > op2
op1
is greater thanop2
>=
op1 >= op2
op1
is greater than or equal toop2
<
op1 < op2
op1
is less thanop2
<=
op1 <= op2
op1
is less than or equal toop2
==
op1 == op2
op1
andop2
are equal!=
op1 != op2
op1
andop2
are not equalRelational operators often are used with the conditional operators to construct more complex decision-making expressions. One such operator is
&&
, which performs the boolean and operation. For example, you can use two different relational operators along with&&
to determine if both relationships are true. The following line of code uses this technique to determine if an array index is between two boundaries. It determines if the index is both greater than 0 and less thanNUM_ENTRIES
(which is a previously defined constant value):Note that in some instances, the second operand to a conditional operator may not be evaluated. Consider this statement:0 < index && index < NUM_ENTRIESIf((count > NUM_ENTRIES) && (in.read() != -1))count
is less thanNUM_ENTRIES
, the left-hand operand for&&
evaluates to false. The&&
operator will return true only if both operands are true. So in this situation, the return value of&&
can be determined without evaluating the right-hand operand. In such a case, Java will not evaluate the right-hand operand. Thus,in.read
won't get called and a character will not be read from standard input.The operator
&
is similar to&&
if both of its operands are of boolean type. However,&
always evaluates both of its operands and returnstrue
if both aretrue
. Likewise,|
is similar to||
if both of its operands are boolean. This operator always evalutes both of its operands and returnsfalse
if they are bothfalse
.Java supports five binary conditional operators, shown in the following table:
In addition, Java supports one other conditional operator--the
Operator Use Returns true
if&&
op1 && op2
op1
andop2
are bothtrue
, conditionally evaluatesop2
||
op1 || op2
either op1
orop2
istrue
, conditionally evaluatesop2
!
! op
op
isfalse
&
op1 & op2
op1
andop2
are bothtrue
, always evaluatesop1
andop2
|
op1 | op2
either op1
orop2
istrue
, always evaluatesop1
andop2
?:
operator. This operator is a tertiary operator and is basically short-hand for anif
-else
statement:Theexpression ? op1 : op2?:
operator evaluatesexpression
and returnsop1
if it's true andop2
if it's false.Bitwise Operators
A bitwise operator allows you to perform bit manipulation on data. This table summarizes the bitwise and logical operators available in the Java language.
Operator Use Operation >>
op1 >> op2
shift bits of op1
right by distanceop2
<<
op1 << op2
shift bits of op1
left by distanceop2
>>>
op1 >>> op2
shift bits of op1
right by distanceop2
(unsigned)&
op1 & op2
bitwise and
|
op1 | op2
bitwise or
^
op1 ^ op2
bitwise xor
~
~op2
bitwise complement The three shift operators simply shift the bits of the left-hand operand over by the number of positions indicated by the right-hand operand. The shift occurs in the direction indicated by the operator itself. For example, the following statement, shifts the bits of the integer 13 to the right by one position:
The binary representation of the number 13 is 1101. The result of the shift operation is 1101 shifted to the right by one position--110 or 6 in decimal. Note that the bit farthest to the right falls off the end into the bit bucket. A right shift of 1 bit is equivalent to, but more efficient than, dividing the left-hand operand by 2. A left shift of 1 bit is equivalent to multiplying by 2.13 >> 1;
op1
op2
Result 0 0 0 0 1 0 1 0 0 1 1 1 The bitwise and operation performs the "and" function on each parallel pair of bits in each operand. The "and" function sets the resulting bit to 1 if both operands are 1.
Suppose you were to "and" the values 12 and 13:
The result of this operation is 12. Why? Well, the binary representation of 12 is 1100, and the binary representation of 13 is 1101. The "and" function sets the resulting bit to 1 if both operand bits are 1, otherwise, the resulting bit is 0. So, if you line up the two operands and perform the "and" function, you can see that the two high-order bits (the two bits farthest to the left of each number) of each operand are 1. Thus the resulting bit in the result is also 1. The low-order bits evaluate to 0 because either one or both bits in the operands are 0:12 & 13The1101 & 1100 ------ 1100|
operator performs the inclusive or operation and^
performs the exclusive or operation. Inclusive or means that if either of the two bits are 1 then the result is 1. The following table shows the results of your inclusive or operations:
op1
op2
Result 0 0 0 0 1 1 1 0 1 1 1 1 Exclusive or means that if the two operand bits are different the result is 1, otherwise the result is 0. The following table shows the results of your exclusive or operation.
op1
op2
Result 0 0 0 0 1 1 1 0 1 1 1 0 And finally, the complement operator inverts the value of each bit of the operand: if the operand bit is 1 the result is 0 and if the operand bit is 0 the result is 1.
Among other things, bitwise manipulations are useful for managing sets of boolean flags. Suppose for example, that you had several boolean flags in your program that indicated the state of various components in your program: is it visible, is it draggable, and so on. Rather than define a separate boolean variable to hold each flag, you could define a single variable,
flags
, for all of them. Each bit withinflags
would represent the current state of one of the flags. You would then use bit manipulations to set and get each flag.First, set up constants that indicated the various flags for your program. These flags should each be a different power of two to ensure that the "on" bit didn't overlap with another flag. Define a variable,
flags
, whose bits would be set according to the current state of each flag. The following code sample initializesflags
to 0 which means that all flags are false (none of the bits are set).To set the "visible" flag when something became visible you would use this statement:final int VISIBLE = 1; final int DRAGGABLE = 2; final int SELECTABLE = 4; final int EDITABLE = 8; int flags = 0;To test for visibility, you could then write:flags = flags | VISIBLE;flags & VISIBLEAssignment Operators
You use the basic assignment operator,=
, to assign one value to another. ThecountChars
method uses=
to initializecount
with this statement:Java also provides several short cut assignment operators that allow you to perform an arithmetic, logical, or bitwise operation and an assignment operation all with one operator. Suppose you wanted to add a number to a variable and assign the result back into the variable, like this:int count = 0;You can shorten this statement using the short cut operatori = i + 2;+=
.The two previous lines of code are equivalent.i += 2;This table lists the shortcut assignment operators and their lengthy equivalents:
Operator Use Equivalent to +=
op1 += op2
op1 = op1 + op2
-=
op1 -= op2
op1 = op1 - op2
*=
op1 *= op2
op1 = op1 * op2
/=
op1 /= op2
op1 = op1 / op2
%=
op1 %= op2
op1 = op1 % op2
&=
op1 &= op2
op1 = op1 & op2
|=
op1 |= op2
op1 = op1 | op2
^=
op1 ^= op2
op1 = op1 ^ op2
<<=
op1 <<= op2
op1 = op1 << op2
>>=
op1 >>= op2
op1 = op1 >> op2
>>>=
op1 >>>= op2
op1 = op1 >>> op2
The Nuts and Bolts of the Java Language |