2.4. Expressions and Operators
So far in this chapter, we've learned about the
primitive types that Java programs can manipulate and seen how to
include primitive values as
literals
in a Java program. We've also used
variables
as symbolic names that represent, or hold, values. These literals and
variables are the
tokens out of which Java programs
are built.An expression
is the next higher level of structure in a Java program. The Java
interpreter evaluates an expression to compute
its value. The very simplest expressions are called
primary
expressions and consist of literals and variables. So, for
example, the following are all expressions:
1.7 // A floating-point literalWhen the Java interpreter evaluates a literal expression, the
true // A boolean literal
sum // A variable
resulting value is the literal itself. When the interpreter evaluates
a variable expression, the resulting value is the value stored in the
variable.Primary expressions are not very interesting. More complex
expressions are made by using operators to
combine primary expressions. For example, the following expression
uses the assignment operator to combine two primary
expressionsa variable and a floating-point literalinto
an assignment expression:
sum = 1.7But operators are used not only with primary expressions; they can
also be used with expressions at any level of complexity. The
following are all legal expressions:
sum = 1 + 2 + 3*1.2 + (4 + 8)/3.0
sum/Math.sqrt(3.0 * 1.234)
(int)(sum + 33)
2.4.1. Operator Summary
The kinds of expressions you can write
in a programming language depend entirely on the set of operators
available to you. Table 2-4 summarizes the
operators available in Java. The P and A columns of the table specify
the precedence and associativity of each group of related operators,
respectively. These conceptsand the operators
themselvesare explained in
more detail in the following
sections.
2.4.1.1 Precedence
The P column of Table 2-4
specifies the precedence of each operator.
Precedence specifies the order in which operations are performed.
Consider this expression:
a + b * cThe multiplication operator has higher precedence than the addition
operator, so a is added to the product of
b and c. Operator precedence
can be thought of as a measure of how tightly operators bind to their
operands. The higher the number, the more tightly they bind.Default operator
precedence can be
overridden through the use of parentheses that explicitly specify the
order of operations. The previous expression can be rewritten as
follows to specify that the addition should be performed before the
multiplication:
(a + b) * cThe default operator precedence in Java was chosen for compatibility
with C; the designers of C chose this precedence so that most
expressions can be written naturally without parentheses. There are
only a few common Java idioms for which parentheses are required.
Examples include:
// Class cast combined with member access
((Integer) o).intValue( );
// Assignment combined with comparison
while((line = in.readLine( )) != null) { ... }
// Bitwise operators combined with comparison
if ((flags & (PUBLIC | PROTECTED)) != 0) { ... }
2.4.1.2 Associativity
When
an expression involves several operators that have the same
precedence, the operator associativity governs the order in which the
operations are performed. Most operators are left-to-right
associative, which means that the operations are performed from left
to right. The assignment and unary operators,
however, have right-to-left associativity. The A column of Table 2-4
specifies the associativity of each operator or group of operators.
The value L means left to right, and
R means right to left.The additive operators are all left-to-right
associative, so the expression a+b-c is evaluated
from left to right: (a+b)-c. Unary operators and
assignment operators are evaluated from right to left. Consider this
complex expression:
a = b += c = -~dThis is evaluated as follows:
a = (b += (c = -(~d)))As with operator precedence, operator
associativity establishes a default order of evaluation for an
expression. This default order can be overridden through the use of
parentheses. However, the default operator associativity in Java has
been chosen to yield a natural expression syntax, and you rarely need
to alter it.
2.4.1.3 Operand number and type
The fourth column of Table 2-4 specifies the number and type of the operands
expected by each operator. Some operators operate on only one
operand; these are called unary operators. For example, the
unary minus operator changes the sign of
a single number:
-n // The unary minus operatorMost operators, however, are binary operators that operate on two
operand values. The - operator actually comes in
both forms:
a - b // The subtraction operator is a binary operatorJava also defines one ternary operator,
often called the conditional operator. It is like an
if statement inside an expression. Its three
operands are separated by a question mark and a
colon; the second and
third operands must be convertible to the same type:
x > y ? x : y // Ternary expression; evaluates to the larger of x and yIn addition to expecting a certain number of operands, each operator
also expects particular types of
operands. Column four of the table lists the operand types. Some of
the codes used in that column require further explanation:
- number
An integer, floating-point
value, or character (i.e., any primitive type except
boolean). In Java 5.0 and later, autounboxing (see
Section 2.9.7 later in this chapter)
means that the wrapper classes (such as Character,
Integer, and Double) for these
types can be be used in this context as well.- integer
A byte,
short, int,
long, or char value
(long values are not allowed for the array access
operator [ ]). With autounboxing,
Byte, Short,
Integer, Long, and
Character values are also allowed.- reference
An object or array.- variable
A variable or anything else, such as
an array element, to which a value can be assigned
2.4.1.4 Return type
Just as every operator expects its
operands to be of specific types, each operator produces a value of a
specific type. The
arithmetic, increment and decrement,
bitwise, and shift operators return a double if at
least one of the operands is a double. They return
a float if at least one of the operands is a
float. They return a long if at
least one of the operands is a long. Otherwise,
they return an int, even if both operands are
byte, short, or
char types that are narrower than
int.The
comparison, equality, and
boolean operators always return
boolean values. Each
assignment operator returns whatever
value it assigned, which is of a type compatible with the variable on
the left side of the expression. The conditional operator returns the value of
its second or third argument (which must both be of the same type).
2.4.1.5 Side effects
Every operator computes a value based
on one or more operand values. Some operators, however, have
side effects in addition to their basic
evaluation. If an expression contains side effects, evaluating it
changes the state of a Java program in such a way that evaluating the
expression again may yield a different result. For example, the
++ increment operator has the side effect of
incrementing a variable. The expression ++a
increments the variable a and returns the newly
incremented value. If this expression is evaluated again, the value
will be different. The various assignment operators also have side
effects. For example, the expression a*=2 can also
be written as a=a*2. The value of the expression
is the value of a multiplied by 2, but the
expression also has the side effect of storing that value back into
a. The method invocation operator (
) has side effects if the invoked method has side effects.
Some methods, such as Math.sqrt( ), simply compute
and return a value without side effects of any kind. Typically,
however, methods do have side effects. Finally, the
new operator has the profound side effect of
creating a new object.
2.4.1.6 Order of evaluation
When the Java interpreter
evaluates an expression, it performs the various operations in an
order specified by the parentheses in the expression, the
precedence of the operators,
and the associativity of the operators. Before any
operation is performed, however, the interpreter first evaluates the
operands of the operator. (The
exceptions are the &&,
||, and ?: operators, which do
not always evaluate all their operands.) The interpreter always
evaluates operands in order from left to right. This matters if any
of the operands are expressions that contain side effects. Consider this code, for
example:
int a = 2;Although the multiplication is performed before the addition, the
int v = ++a + ++a * ++a;
operands of the + operator are evaluated first.
Thus, the expression evaluates to 3+4*5, or 23.
2.4.2. Arithmetic Operators
Since
most programs operate primarily on numbers, the most commonly used
operators are often those that perform arithmetic operations. The
arithmetic operators can be used with integers, floating-point
numbers, and even characters (i.e., they can be used with any
primitive type other than boolean). If either of
the operands is a floating-point number, floating-point arithmetic is
used; otherwise, integer arithmetic is used. This matters because
integer arithmetic and floating-point arithmetic differ in the way
division is performed and in the way underflows and overflows are
handled, for example. The arithmetic operators are:
- Addition (+ )
The + operator adds two
numbers. As we'll see shortly, the
+ operator can also be used to concatenate
strings. If either operand of + is a string, the
other one is converted to a string as well. Be sure to use
parentheses when you want to combine addition with concatenation. For
example:
System.out.println("Total: " + 3 + 4); // Prints "Total: 34", not 7!
- Subtraction (- )
When the - operator
is used as a binary operator, it subtracts its second operand from
its first. For example, 7-3 evaluates to 4. The -
operator can also perform unary negation.- Multiplication (* )
The * operator
multiplies its two operands. For example, 7*3 evaluates to 21.- Division (/ )
The
/ operator divides its first operand by its
second. If both operands are integers, the result is an integer, and
any remainder is lost. If either operand is a floating-point value,
however, the result is a floating-point value. When dividing two
integers,
division
by zero throws an ArithmeticException. For
floating-point calculations, however, division by zero simply yields
an infinite result or NaN:
7/3 // Evaluates to 2
7/3.0f // Evaluates to 2.333333f
7/0 // Throws an ArithmeticException
7/0.0 // Evaluates to positive infinity
0.0/0.0 // Evaluates to NaN
- Modulo (% )
The %
operator computes the first operand modulo the second operand (i.e.,
it returns the remainder when the first operand is divided by the
second operand an integral number of times). For example, 7%3 is 1.
The sign of the result is the same as the sign of the first operand.
While the modulo operator is typically used with integer operands, it
also works for floating-point values. For example, 4.3%2.1 evaluates
to 0.1. When operating with integers, trying to compute a value
modulo zero causes an ArithmeticException. When
working with floating-point values, anything modulo 0.0 evaluates to
NaN, as does infinity modulo anything.- Unary minus (- )
When
the - operator is used as a unary
operatorthat is, before a single operandit performs
unary negation. In other words, it converts a positive value to an
equivalently negative value, and vice versa.
2.4.3. String Concatenation Operator
In
addition to adding numbers, the
+ operator (and the related +=
operator) also concatenates, or joins, strings. If either of the
operands to + is a string, the operator converts
the other operand to a string. For example:
System.out.println("Quotient: " + 7/3.0f); // Prints "Quotient: 2.3333333"As a result, you must be careful to put any addition expressions in
parentheses when combining them with string concatenation. If you do
not, the addition operator is interpreted as a concatenation
operator.
The Java interpreter has built-in
string conversions for all primitive types. An object is converted to
a string by invoking its toString( ) method. Some
classes define custom toString( ) methods so that
objects of that class can easily be
converted to strings in this way. An array is converted to a string
by invoking the built-in toString( ) method,
which, unfortunately, does not return a useful string representation
of the array contents.
2.4.4. Increment and Decrement Operators
The ++ operator
increments its single operand, which must be a variable, an element
of an array, or a field of an object, by one. The behavior of this
operator depends on its position relative to the operand. When used
before the operand, where it is known as the
pre-increment
operator, it increments the operand and evaluates to the incremented
value of that operand. When used after the operand, where it is known
as the
post-increment operator, it increments its operand,
but evaluates to the value of that operand before it was incremented.For example, the following code sets both i and
j to 2:
i = 1;But these lines set i to 2 and
j = ++i;
j to 1:
i = 1;Similarly, the
j = i++;
-- operator decrements its single numeric
operand, which must be a variable, an element of an array, or a field
of an object, by one. Like the ++ operator, the
behavior of -- depends on its position relative to
the operand. When used before the operand, it decrements the operand
and returns the decremented value. When used after the operand, it
decrements the operand, but returns the
undecremented value.The expressions x++ and x-- are
equivalent to x=x+1 and x=x-1,
respectively, except that when using the increment and decrement
operators, x is only evaluated once. If
x is itself an expression with side effects, this
makes a big difference. For example, these two expressions are not
equivalent:
a[i++]++; // Increments an element of an arrayThese operators, in both prefix and postfix forms, are most commonly
a[i++] = a[i++] + 1; // Adds one to an array element and stores it in another
used to increment or decrement the counter that controls a
loop.
2.4.5. Comparison Operators
The comparison operators consist of
the equality operators that test values for equality or inequality
and the relational operators used with ordered types (numbers and
characters) to test for greater than and less than relationships.
Both types of operators yield a boolean result, so
they are typically used with if statements and
while and for loops to make
branching and looping decisions. For example:
if (o != null) ...; // The not equals operatorJava provides the following equality operators:
while(i < a.length) ...; // The less than operator
- Equals (= = )
The = = operator
evaluates to TRue if its two operands are equal
and false otherwise. With primitive operands, it tests whether the
operand values themselves are identical. For operands of
reference types, however, it tests
whether the operands refer to the same object or array. In other
words, it does not test the equality of two distinct objects or
arrays. In particular, note that you cannot test two distinct strings
for equality with this operator.If = = is used to
compare two numeric or character operands that are not of the same
type, the narrower operand is converted to the type of the wider
operand before the comparison is done. For example, when comparing a
short to a float, the
short is first converted to a
float before the comparison is performed. For
floating-point numbers, the special negative zero value tests equal
to the regular, positive zero value. Also, the special NaN
(not-a-number) value is not equal to any other number, including
itself. To test whether a floating-point value is NaN, use the
Float.isNan( ) or Double.isNan(
) method.- Not equals (!= )
The !=
operator is exactly the opposite of the = =
operator. It evaluates to true if its two
primitive operands have different values or if its two reference
operands refer to different objects or arrays. Otherwise, it
evaluates to false.
The relational operators can be used
with numbers and characters, but not with boolean
values, objects, or arrays because those types are not ordered. Java
provides the following relational operators:
- Less than (< )
Evaluates to true if the first operand is less
than the second.- Less than or equal (<= )
Evaluates to
true if the first operand is less than or equal to
the second.- Greater than (> )
Evaluates to
TRue if the first operand is greater than the
second.- Greater than or equal (>= )
Evaluates to
true if the first operand is greater than or equal
to the second.
2.4.6. Boolean Operators
As
we've just seen, the comparison operators compare
their operands and yield a boolean result, which
is often used in branching and looping statements. In order to make
branching and looping decisions based on conditions more interesting
than a single comparison, you can use the boolean (or logical)
operators to combine multiple comparison expressions into a single,
more complex expression. The boolean operators require their operands
to be boolean values and they evaluate to
boolean values. The operators are:
- Conditional AND (&& )
This operator performs a boolean AND
operation on its operands. It evaluates to true if
and only if both its operands are true. If either
or both operands are false, it evaluates to
false. For example:
if (x < 10 && y > 3) ... // If both comparisons are trueThis operator (and all the boolean operators except the unary
! operator) have a lower
precedence than the
comparison operators. Thus, it is perfectly legal to write a line of
code like the one above. However, some programmers prefer to use
parentheses to make the order of evaluation explicit:
if ((x < 10) && (y > 3)) ...You should use whichever style you find easier to
read.This operator is called a conditional AND because it conditionally
evaluates its second operand. If the first operand evaluates to
false, the value of the expression is
false, regardless of the value of the second
operand. Therefore, to increase efficiency, the Java interpreter
takes a shortcut and skips the second operand. Since the second
operand is not guaranteed to be evaluated, you must use caution when
using this operator with expressions that have side effects. On the
other hand, the conditional nature of this operator allows us to
write Java expressions such as the following:
if (data != null && i < data.length && data[i] != -1)The second and third comparisons in this expression would cause
...
errors if the first or second comparisons evaluated to
false. Fortunately, we don't have
to worry about this because of the conditional behavior of the
&& operator.
- Conditional OR (|| )
This operator performs a boolean OR
operation on its two boolean operands. It
evaluates to TRue if either or both of its
operands are TRue. If both operands are
false, it evaluates to false.
Like the && operator,
|| does not always evaluate its second operand. If
the first operand evaluates to true, the value of
the expression is true, regardless of the value of
the second operand. Thus, the operator simply skips the second
operand in that case.- Boolean NOT (! )
This unary operator changes the
boolean value of its operand. If applied to a
true value, it evaluates to
false, and if applied to a
false value, it evaluates to
TRue. It is useful in expressions like these:if (!found) ... // found is a boolean variable declared somewhere
Because ! is a unary operator, it has a high
while (!c.isEmpty( )) ... // The isEmpty( ) method returns a boolean value
precedence and often must be used with
parentheses:if (!(x > y && y > z))
- Boolean AND (& )
When used with boolean
operands, the & operator behaves like the
&& operator, except that it always
evaluates both operands, regardless of the value of the first
operand. This operator is almost always used as a bitwise operator
with integer operands, however, and many Java programmers would not
even recognize its use with boolean operands as
legal Java code.- Boolean OR (| )
This operator performs a boolean OR
operation on its two boolean operands. It is like
the || operator, except that it always evaluates
both operands, even if the first one is true. The
| operator is almost always used as a bitwise
operator on integer operands; its use with boolean
operands is very rare.- Boolean XOR (^ )
When used with
boolean operands, this operator computes the
Exclusive OR (XOR) of its operands. It evaluates to
true if exactly one of the two operands is
true. In other words, it evaluates to
false if both operands are
false or if both operands are
true. Unlike the && and
|| operators, this one must always evaluate both
operands. The ^ operator is much more commonly
used as a bitwise operator on integer operands. With
boolean operands, this operator is equivalent to
the != operator.
2.4.7. Bitwise and Shift Operators
The bitwise and shift operators are
low-level operators that manipulate the individual bits that make up
an integer value. The bitwise operators are most commonly used for
testing and setting individual flag bits in a value. In order to
understand their behavior, you must understand binary (base-2)
numbers and the twos-complement format used to represent
negative integers. You cannot use
these operators with floating-point, boolean,
array, or object operands. When used with boolean
operands, the &, |, and
^ operators perform a different operation, as
described in the previous section.If either of the arguments to a bitwise operator is a
long, the result is a long.
Otherwise, the result is an int. If the left
operand of a shift operator is a long, the result
is a long; otherwise, the result is an
int. The operators are:
- Bitwise complement (~ )
The unary ~
operator is known as the bitwise complement, or bitwise NOT,
operator. It inverts each bit of its single operand, converting ones
to zeros and zeros to ones. For example:
byte b = ~12; // ~00001100 = => 11110011 or -13 decimal
flags = flags & ~f; // Clear flag f in a set of flags
- Bitwise AND (& )
This operator combines
its two integer operands by performing a boolean AND operation on
their individual bits. The result has a bit set only if the
corresponding bit is set in both operands. For example:
10 & 7 // 00001010 & 00000111 = => 00000010 or 2When used with boolean operands,
if ((flags & f) != 0) // Test whether flag f is set
& is the infrequently used boolean AND
operator described earlier.
- Bitwise OR (| )
This operator combines its two
integer operands by performing a boolean OR operation on their
individual bits. The result has a bit set if the corresponding bit is
set in either or both of the operands. It has a zero bit only where
both corresponding operand bits are zero. For example:
10 | 7 // 00001010 | 00000111 = => 00001111 or 15When used with boolean operands,
flags = flags | f; // Set flag f
| is the infrequently used boolean OR operator
described earlier.
- Bitwise XOR (^ )
This operator combines
its two integer operands by performing a boolean XOR (Exclusive OR)
operation on their individual bits. The result has a bit set if the
corresponding bits in the two operands are different. If the
corresponding operand bits are both ones or both zeros, the result
bit is a zero. For example:
10 ^ 7 // 00001010 ^ 00000111 = => 00001101 or 13When used with boolean operands,
^ is the infrequently used boolean XOR operator.
- Left shift (<< )
The <<
operator shifts the bits of the left operand left by the number of
places specified by the right operand. High-order bits of the left
operand are lost, and zero bits are shifted in from the right.
Shifting an integer left by n places is
equivalent to multiplying that number by
2n. For example:
10 << 1 // 00001010 << 1 = 00010100 = 20 = 10*2If the left operand is a long, the right operand
7 << 3 // 00000111 << 3 = 00111000 = 56 = 7*8
-1 << 2 // 0xFFFFFFFF << 2 = 0xFFFFFFFC = -4 = -1*4
should be between 0 and 63. Otherwise, the left operand is taken to
be an int, and the right operand should be between
and 31.
- Signed right shift (>> )
The
>> operator shifts the bits of the left
operand to the right by the number of places specified by the right
operand. The low-order bits of the left operand are shifted away and
are lost. The high-order bits shifted in are the same as the original
high-order bit of the left operand. In other words, if the left
operand is positive, zeros are shifted into the high-order bits. If
the left operand is negative, ones are shifted in instead. This
technique is known as sign extension ; it is used
to preserve the sign of the left operand. For example:
10 >> 1 // 00001010 >> 1 = 00000101 = 5 = 10/2If the left operand is positive and the right operand is
27 >> 3 // 00011011 >> 3 = 00000011 = 3 = 27/8
-50 >> 2 // 11001110 >> 2 = 11110011 = -13 != -50/4
n, the >>
operator is the same as integer division by
2n.
- Unsigned right shift (>>> )
This operator is like the
>> operator, except that it always shifts
zeros into the high-order bits of the result, regardless of the sign
of the left-hand operand. This technique is called zero
extension ; it is appropriate when the left operand is
being treated as an unsigned value (despite the fact that Java
integer types are all signed). These are examples:
0xff >>> 4 // 11111111 >>> 4 = 00001111 = 15 = 255/16
-50 >>> 2 // 0xFFFFFFCE >>> 2 = 0x3FFFFFF3 = 1073741811
2.4.8. Assignment Operators
The assignment operators store, or
assign, a value into some kind of variable. The left operand must
evaluate to an appropriate local variable, array element, or object
field. The right side can be any value of a type compatible with the
variable. An assignment expression evaluates to the value that is
assigned to the variable. More importantly, however, the expression
has the side effect of actually performing the assignment. Unlike all
other binary operators, the assignment operators are
right-associative, which means that the assignments in
a=b=c are performed right-to-left, as follows:
a=(b=c).The basic assignment operator is
=. Do not confuse it with the equality operator,
= =. In order to keep these two operators
distinct, I recommend that you read = as
"is assigned the value." In addition to this simple assignment
operator, Java also defines 11 other operators that
combine assignment with the 5
arithmetic operators and the 6 bitwise and shift operators. For
example, the += operator reads the value of the left
variable, adds the value of the right operand to it, stores the sum
back into the left variable as a side effect, and returns the sum as
the value of the expression. Thus, the expression
x+=2 is almost the same as
x=x+2. The difference between these two
expressions is that when you use the += operator,
the left operand is evaluated only once. This makes a difference when
that operand has a side effect. Consider the following two
expressions, which are not equivalent:
a[i++] += 2;The general form of these combination assignment operators is:
a[i++] = a[i++] + 2;
var op= valueThis is equivalent (unless there are side effects in
var) to:
var = var op valueThe available operators are:
+= -= *= /= %= // Arithmetic operators plus assignmentThe most commonly used operators are += and
&= |= ^= // Bitwise operators plus assignment
<<= >>= >>>= // Shift operators plus assignment
-=, although &= and
|= can also be useful when working with
boolean flags. For example:
i += 2; // Increment a loop counter by 2
c -= 5; // Decrement a counter by 5
flags |= f; // Set a flag f in an integer set of flags
flags & ~f; // Clear a flag f in an integer set of flags
2.4.9. The Conditional Operator
The
conditional operator ?: is a somewhat obscure
ternary (three-operand) operator inherited from C. It allows you to
embed a conditional within an expression. You can think of it as the
operator version of the if/else statement. The
first and second operands of the conditional operator are separated
by a question mark (?) while the second and third
operands are separated by a colon (:).
The first operand must evaluate to a
boolean value. The second and third operands can
be of any type, but they must be convertible to the same type.The conditional operator starts by evaluating its first operand. If
it is TRue, the operator evaluates its second
operand and uses that as the value of the expression. On the other
hand, if the first operand is false, the
conditional operator evaluates and returns its third operand. The
conditional operator never evaluates both its second and third
operand, so be careful when using expressions with side effects with
this operator. Examples of this operator are:
int max = (x > y) ? x : y;Note that the ?: operator has lower
String name = (name != null) ? name : "unknown";
precedence than all other operators
except the assignment operators, so parentheses are not usually
necessary around the operands of this operator. Many programmers find
conditional expressions easier to read if the first operand is placed
within parentheses, however. This is especially
true because the conditional if statement always
has its conditional expression written within parentheses.
2.4.10. The instanceof Operator
The
instanceof operator requires an object or array
value as its left operand and the name of a reference type as its
right operand. It evaluates to true if the object
or array is an instance of the specified type;
it returns false otherwise. If the left operand is
null, instanceof always
evaluates to false. If an
instanceof expression evaluates to
true, it means that you can safely cast and assign
the left operand to a variable of the type of the right operand.The
instanceof operator can be used only with
reference types and
objects, not primitive types and values. Examples of
instanceof are:
"string" instanceof String // True: all strings are instances of String
" instanceof Object // True: strings are also instances of Object
null instanceof String // False: null is never an instance of anything
Object o = new int[] {1,2,3};
o instanceof int[] // True: the array value is an int array
o instanceof byte[] // False: the array value is not a byte array
o instanceof Object // True: all arrays are instances of Object
// Use instanceof to make sure that it is safe to cast an object
if (object instanceof Point) {
Point p = (Point) object;
}
2.4.11. Special Operators
Java has five language constructs
that are sometimes considered operators and sometimes considered
simply part of the basic language syntax. These
"operators" were included in Table 2-4 in order to show their precedence relative to
the other true operators. The use of these language constructs is
detailed elsewhere in this book but is described briefly here so that
you can recognize them in code examples.
- Object member access (.)
An object is a
collection of data and methods that operate on that data; the data
fields and methods of an object are called its members. The dot
(.) operator accesses these members. If
o is an expression that evaluates to an object
reference, and f is the name of a field of the
object, o.f evaluates to the value contained in
that field. If m is the name of a method,
o.m refers to that method and allows it to be
invoked using the ( ) operator shown later.- Array element access ([] )
An
array is a numbered list of values. Each element
of an array can be referred to by its number, or
index . The [ ] operator
allows you to refer to the individual elements of an array. If
a is an array, and i is an
expression that evaluates to an int,
a[i] refers to one of the elements of
a. Unlike other operators that work with integer
values, this operator restricts array index values to be of type
int or narrower.- Method invocation (( ) )
A method is a
named collection of Java code that can be run, or
invoked , by following the name of the method
with zero or more comma-separated expressions contained within
parentheses. The values of these expressions are the
arguments to the method. The method processes
the arguments and optionally returns a value that becomes the value
of the method invocation expression. If o.m is a
method that expects no arguments, the method can be invoked with
o.m( ). If the method expects three arguments, for
example, it can be invoked with an expression such as
o.m(x,y,z). Before the Java interpreter invokes a
method, it evaluates each of the arguments to be passed to the
method. These expressions are guaranteed to be evaluated in order
from left to right (which matters if any of the arguments have side
effects).- Object creation (new )
In Java, objects (and
arrays) are created with the new operator, which
is followed by the type of the object to be created and a
parenthesized list of arguments to be passed to the object
constructor . A constructor is a special method
that initializes a newly created object, so the object creation
syntax is similar to the Java method invocation syntax. For example:
new ArrayList( );
new Point(1,2)
- Type conversion or casting (( ) )
As we've already
seen, parentheses can also be used as an operator to perform
narrowing type conversions, or casts. The first operand of this
operator is the type to be converted to; it is placed between the
parentheses. The second operand is the value to be converted; it
follows the parentheses. For example:
(byte) 28 // An integer literal cast to a byte type
(int) (x + 3.14f) // A floating-point sum value cast to an integer value
(String)h.get(k) // A generic object cast to a more specific string type