Looks and behaves like algebra, using variable names and math symbols:
int a, b, c, temp; a = b/c + temp; b = c * (a  b);
=
sign is called an lvalue. Only things that can accept a value can be an lvalue
(usually this means a variable name  you can't have a calculation like a + b
in front of the equal sign).Operator  Purpose (Operation Performed) 

+ 
for addition 
 
for subtraction 
* 
for multiplication 
/ 
for division 
% 
for modulus (remainder after division) 
( and ) 
for enclosing a calculation 
An expression is anything that can be evaluated to produce a value. Every expression yields a value.
Two simple expressions:
a + 5 5/c
An expression that contains another expression inside, the (5/c)
part:
b + (5/c)
A statement is an expression; this one that contains another expression inside  the b + (5/c)
part, which itself contains an expression inside it (the 5/c
part):
a = b + (5/c);
Since an assignment statement (using the =
sign) is an expression, it also yields a value (the value stored is considered the result of the expression), which allows things like this:
d = a = b + (5/c);
a
is the value of the expression b + (5/c)
.d
.b
.5
stored somewhere in memory by the compiler.c
.5 / c
b
to the result of the above step.a
.d
.Here is a moderately complicated expression; let's say that a
, b
, and c
are all double
variables, and that a
is 5.0
, b
is 10.0
, and c
is 20.0
:
d = a + b * Math.sqrt(c + 5);
c + 5
is in parentheses, the compiler creates code to evaluate that first, but to perform the c + 5
operation, both elements must be the same type of data, so the thing the compiler creates is a conversion for the 5
to 5.0
as a double
.
d = a + b * Math.sqrt(c + 5.0);
20.0 + 5.0
(at runtime it would become 25.0
), reducing the expression to:
d = a + b * Math.sqrt(25.0);
Math.sqrt
method to evaluate its result, which will be 5.0
, so the expression reduces to:
d = a + b * 5.0;
d = a + 50.0;
d = 55.0;
55.0
is stored in d
.As implied by the examples we have seen so far, the order of evaluation of a complex expression is not necessarily from left to right. There is a concept called operator precedence that defines the order of operations.
Operator precedence specifies the order of evaluation of an expression.
Every language has a "table of operator precedence" that is fairly long and complex, but most languages follow the same general rules:
a = b + 5/c
, the 5/c
gets calculated
first, then the result is added to b
, then the overall result
is stored in a
.=
) is an operator; where on the table do you think it is located?The basic rule programmers follow is: when in doubt about the order of precedence, use parentheses.
Try the following program:
public class ExpressionExample { public static void main(String[] args) { double a = 5.0, b = 10.0, c = 20.0; System.out.println("a+b is " + (a + b)); System.out.println("a+b/c is " + (a + b / c)); System.out.println("a*b+c is " + (a * b + c)); System.out.println("b/a+c/a is " + (b / a + c / a)); } }
Every expression has a value. For an assignment expression, the value assigned is the expression's overall value. This enables chaining of assignments:
x = y = z + 1;
is the same as y = z + 1; x = y;
i = (j = k + 1)/2;
is the same as j = k + 1; i = j/2;
Quite often, you may need to calculate a value involved in a test, but also store the value for later use:
double x; if ( (x = Math.random()) < 0.5 ) { System.out.println(x); }
You might wonder why not just generate the random number when we declare x? In this case, that would make sense, but in a loop the approach shown above might be easier such that:
x
.0.5
, and the loop body executes if that is true.It is usually not necessary to code this way, but you will see it often.
The order of operand evaluation is always left to right, regardless of the precedence of the operators involved.
public class EvaluationOrder { public static int getA() { System.out.println("getA is 2"); return 2; } public static int getB() { System.out.println("getB is 3"); return 3; } public static int getC() { System.out.println("getC is 4"); return 4; } public static void main(String[] args) { int x = getA() + getB() * getC(); System.out.println("x = " + x); } }
The operands are first evaluated in left to right order, so that
the functions are called in the order getA()
, then getB()
,
and, lastly, getC()
But, the returned values are combined together by multiplying the results of getB()
and getC()
, and then adding the result from getA()
Java has a number of operators for working with the individual bits within a value.
Operator 
Description 


Example 
Effect 
Bit Pattern 

& 
Bitwise AND, combines individual bits with an AND operation, so that in the resulting value, a bit position is only 1 if that position had a 1 for both operands.  
int a = 2; 
has the 2 bit set  0...00000010 

int b = 6; 
has the 2 and 4 bits set  0...00000110 

int c = a & b; 
results in 2  0...00000010 

 
Bitwise OR, combines individual bits with an OR operation, so that in the resulting value, a bit position is 1 if that position had a 1 for either operand.  
int a = 2; 
has the 2 bit set  0...00000010 

int b = 4; 
has the 4 bit set  0...00000100 

int c = a  b; 
results in 6  0...00000110 

^ 
Bitwise exclusive OR (XOR), combines individual bits so that any position that is the same in both operands yields a 0, any bits that differ yield a 1 in that position; this is often used in encryption, since repeating the operation on the result yields the original value again  
int a = 3; 
has the 1 and 2 bits set  0...00000011 

int b = 6; 
has the 2 and 4 bits set  0...00000110 

int c = a ^ b; 
results in 5  0...00000101 

int d = c ^ b; 
results in 3 again  0...00000011 

~ 
Bitwise complement. Reverses the state of all bits.  
int a = 0; 
has no bits set  0...00000000 

int b = ~a; 
has all bits set  1...11111111 
These operators shift the bits left or right within a 32bit int
value (they do not work with any other type).
Operator  Description  

Example  Effect  Bit Pattern  
<< 
left shift the bits by the second operand  
int a = 4; 
has the 4 bit set  0...00000010 

int b = a << 2; 
now has the 16 bit set  0...00001000 

>> 
right shift the bits by the second operand with signextension (if the first bit is a 1, new bits introduced to fill in on the left come in as 1 bits)  
int a = 126; 
has all bits except the rightmost set to 1  10...0000010 

int b = a >> 1; 
now has all bits set to 1 (the 0 rolled off the right end, and a 1 was added on the left to match the original leftmost bit; the resulting value is 63)  110...000001 

>>> 
right shift the bits by the second operand without signextension (bits added on the left always come in as 0)  
int a = 1; 
has all bits set to 1  11...1111111 

int b = a >>> 31; 
now has all bits set to 0 except the rightmost (all bits except the first rolled off the right end, and 0's were added on the left  0000000...01 
Combine multiple effects in one operation: calculation and storage into memory
Operator 
Purpose (Operation Performed) 

++ 
increment a variable 
 
decrement a variable; note that ++ and  can precede or follow a variable 
if preceding (called prefix), apply the operator and then use the resulting value  
if following (called postfix), retrieve the value of the variable first, use it as the result of the expression, and then apply the operator  
+= 
add an amount to a variable 
= 
subtract an amount from a variable 
*= 
multiply a variable by an amount 
/= 
divide a variable by an amount 
%= 
set variable equal to remainder after division by an amount 
&= 
perform bitwise AND between left and right, store result into left operand 
= 
perform bitwise OR between left and right, store result into left operand 
^= 
perform bitwise XOR between left and right, store result into left operand 
>>= 
shift the variable's bits to the right by an amount with signextension 
>>>= 
shift the variable's bits to the right by an amount without signextension 
<<= 
shift the variable's bits to the left by an amount 
Statement 
Result 

i++; 
increment i 
i; 
decrement i 
j = i++; 
retrieve current value of i, hold it as the result of the expression, assign its value to j , then increment i 
j = ++i; 
increment i , then j = i; 
x *= 3; 
x = x * 3; 
y = z + 5; 
y = y  (z + 5); 
It is inevitable that a certification exam will ask a question that requires understanding the steps involved in a postfix increment or decrement: try the following program:
public class IncrementTest { public static void main(String[] args) { int i = 0, j; i = i++; System.out.println("i = " + i); j = i++ + i; System.out.println("i = " + i + ", j = " + j); } }
i = i++;
, the original value of i
(0) is retrieved and held. Then, i
is incremented. But, after that, the held value of 0 is put back into i
, overwriting the 1!j = i++ + i;
, the operands are evaluated from left to right, but each operand is fully evaluated before proceeding to the next. Which means that the increment part of i++
has taken effect before the second appearance of i
in the equation, so that the expression reduces to 0 + 1 (recall that the previous operation resulted in i
being 0).Expressions will often mix different types of data, for example:
double x = 15.6 / 4; double y = 12.2 + 15 / 4;
The compiler must choose a specific type of data (either integer or floatingpoint, and the specific size) for each individual expression it evaluates within a statement.
double
, which will then be used in the division.double
to finish the statement.The process of changing the data type of a value is known a typecasting (or casting):
double
to int
)  this must be coded with an explicit cast.int a = (int) (15.6 / 4);
double
, and the result is a double
, but a double
can't be stored in a,
so the cast to int
is necessary.The allowable sequence of implicit casts is shown below:
One aspect of Java that is important to understand is the result of expressions involving the small integral types: byte
, char
, and short
any expression involving these types, other than the compound assignment expressions, is done with int
values, so that the result will always be an int
.
Try the following (it is the same as the earlier postfix increment example, using byte
instead of int
):
byte i = 0, j = 6, k; i++; k = i + j; System.out.println("i = " + i + ", j = " + j);
Note that the increment expression is accepted by the compiler; it is the simple addition in the third line that causes an error.
The Java Language Specification states the promotion rules as follows (note that this concept does not apply to all operators; again, the operators that include assignment do not use it):
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversions to convert operands as necessary:
double
, the other is converted to double
. float
, the other is converted to float
. long
, the other is converted to long
. int
.