I'll try to answer this with some references, so that you can go into whatever depth you want. It's not entirely clear what is confusing you.
Firstly, you need to be clear on the difference between assignment operators (= in your examples, but these also include e.g. += etc) and other (binary) operators (e.g. +,-,*,% etc). Assignment operators (such as =) evaluate right to left - i.e. they work out the value of everything on the right of the operator and then assign it to whatever is on the left.
For other operators, they first apply operator precedence and then apply left to right operation on operators with equal precedence. A table of precedence and discussion of this is available in the official tutorial. It is very similar to the table (Fig A.1) on p.1509 of the book you are using, but the web tutorial explanation may be easier to understand. It can be summed up as precedence being applied as expressions in brackets first, followed by postfix then unary operators (e.g. x++, then -x), then multiplicative operators (*,\,%) and then additive (+,-) and finally lots of logical operators that are not directly relevant to this question.
Finally, the tutorial contains the statement
When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
Crucially, the precedence then left-to-right evaluation will be repeated, most easily illustrated by going through your example step by step:
(4 * 4) + (8 * 8) * (4 * 4) - 16/4
// Found brackets - highest precedence.
// more than one, so evaluate left to right
16 + (8 * 8) * (4 * 4) - 16/4
16 + 64 * (4 * 4) - 16/4
16 + 64 * 16 - 16/4
//brackets finished, back to precedence. Found multiplicative operators
//evaluate left to right
16 + 1024 - 16/4
16 + 1024 - 4
//multiplicative finished, back to precedence. Found additive operators
//evaluate left to right
1040 - 4
1036
// Expression fully evaluated. Can now be used / assigned to a variable
Addendum
The definitive specification for the evaluation of expressions is in the Java Language Specification chapter 15. It's probably more confusing than helpful at this level, but I include it for completeness. Section 15.7.3 deals with respecting brackets (parantheses) around expressions and operator precedence.
Answer from J Richard Snape on Stack OverflowVideos
I'll try to answer this with some references, so that you can go into whatever depth you want. It's not entirely clear what is confusing you.
Firstly, you need to be clear on the difference between assignment operators (= in your examples, but these also include e.g. += etc) and other (binary) operators (e.g. +,-,*,% etc). Assignment operators (such as =) evaluate right to left - i.e. they work out the value of everything on the right of the operator and then assign it to whatever is on the left.
For other operators, they first apply operator precedence and then apply left to right operation on operators with equal precedence. A table of precedence and discussion of this is available in the official tutorial. It is very similar to the table (Fig A.1) on p.1509 of the book you are using, but the web tutorial explanation may be easier to understand. It can be summed up as precedence being applied as expressions in brackets first, followed by postfix then unary operators (e.g. x++, then -x), then multiplicative operators (*,\,%) and then additive (+,-) and finally lots of logical operators that are not directly relevant to this question.
Finally, the tutorial contains the statement
When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
Crucially, the precedence then left-to-right evaluation will be repeated, most easily illustrated by going through your example step by step:
(4 * 4) + (8 * 8) * (4 * 4) - 16/4
// Found brackets - highest precedence.
// more than one, so evaluate left to right
16 + (8 * 8) * (4 * 4) - 16/4
16 + 64 * (4 * 4) - 16/4
16 + 64 * 16 - 16/4
//brackets finished, back to precedence. Found multiplicative operators
//evaluate left to right
16 + 1024 - 16/4
16 + 1024 - 4
//multiplicative finished, back to precedence. Found additive operators
//evaluate left to right
1040 - 4
1036
// Expression fully evaluated. Can now be used / assigned to a variable
Addendum
The definitive specification for the evaluation of expressions is in the Java Language Specification chapter 15. It's probably more confusing than helpful at this level, but I include it for completeness. Section 15.7.3 deals with respecting brackets (parantheses) around expressions and operator precedence.
Usually, the code is always read from left to right, but also follows the math precedence. Example:
(4 * 4) + (8 * 8) * (4 * 4) - 16/4
Math says in this case: Parentheses first, multiplication and division after, and then addition and subtraction. Then:
//Parenthesis done
(16) + (64) * (16) - 16/4
//Multiplication and division done
16 + 1024 - 4
//Addition and subtraction done
1036
Almost everybody so far has confused order of evaluation with operator precedence. In Java the precedence rules make the expression equivalent to the following:
a + (b * c) / ( d - e )
because * and / have equal precedence and are left associative.
The order of evaluation is strictly defined as left hand operand first, then right, then operation (except for || and &&). So the order of evaluation is:
a
b
c
*
d
e
-
/
+
order of evaluation goes down the page. Indentation reflects the structure of the syntax tree
Edit
In response to Grodriguez's comments. The following program:
public class Precedence
{
private static int a()
{
System.out.println("a");
return 1;
}
private static int b()
{
System.out.println("b");
return 2;
}
private static int c()
{
System.out.println("c");
return 3;
}
private static int d()
{
System.out.println("d");
return 4;
}
private static int e()
{
System.out.println("e");
return 5;
}
public static void main(String[] args)
{
int x = a() + b() * c() / (d() - e());
System.out.println(x);
}
}
Produces the output
a
b
c
d
e
-5
which clearly shows the multiplication is performed before the subtraction.
As JeremyP has nicely shown us, the first answer is correct.
In general, the following rules apply:
- Every operand of an operator is evaluated before the operation itself is performed (except for
||,&&, and?:) - Operands are evaluated left to right. The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
- The order of evaluation respects parentheses and operator precedence:
- Parentheses are evaluated first.
- Operators are evaluated in order of precedence.
- Operators with equal precedence are evaluated left-to-right, except for assignment operators which are evaluated right-to-left.
Note that the first two rules explain the result in your second question:
int i = 2;
System.out.println(i * (i=3)); // prints '6'
int j = 2;
System.out.println((j=3) * j); // prints '9'
Reference documentation:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#4779
Tutorial:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
"These operators have different precedence, with & having the highest precedence and | the lowest precedence".
Just because they have higher precedence, doesn't mean their operands will be evaluated first.
This
Copyboolean bool = isTrue1() | isFalse1() & isFalse2() ;
becomes equivalent to
Copyboolean bool = isTrue1() | ( isFalse1() & isFalse2() ) ;
That's all precedence is.
As the Java Language Specification says, operator operands are evaluated left to right.
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
The & has higher precedence than | but in your case, evaluating this:
Copyboolean bool = isTrue1() | isFalse1() & isFalse2()
is the same as evaluating this:
Copy boolean bool = (isTrue1()) | (isFalse1() & isFalse2())
Which means, the two sides of the | expression are the same precedence. So java will evaluate them in the left-to-right order in that case.
First it will call isTrue1(), being the first on the left and then the second paranthesis, again evaluating what is inside it in the left-to-right order: isFalse1() and then isFalse2().