Because multiplication shall be evaluated before addition.
As you seem to mean it, that's not a reasonable description of the precedence of multiplication over addition, nor of the effect of section 15.7.3. Precedence says that your expression
f1() + f2()*f3()
is evaluated the same as
f1() + (f2() * f3())
, as opposed to the same as
(f1() + f2()) * f3()
Precedence does not speak to which operand of the +
operator is evaluated first, regardless of the nature of the operands. It speaks instead to what each operand is. This does impact order of evaluation, in that it follows from precedence rules that the result of the multiplication in your original expression must be computed before the result of the addition, but that does not speak directly to the question of when the values of two factors are evaluated relative to each other or to other sub-expressions.
Different rules than the one you quoted are responsible for the order in which the two operands of a +
or *
operator are evaluated -- always the left operand first and the right operand second.
How exactly operator precedence is respected in this example?
The example's output does not convey information about whether precedence -- understood correctly -- is respected. The same output would be observed for both of the two parenthesized alternatives above, and precedence is about which one of those two is equivalent to the original expression.
In an order-of-operations sense, precedence says (only) that the right-hand operand of the addition is f2()*f3()
, which means that product must be computed before the overall sum can be. JLS 15.7.3 isn't saying anything more than or different from that. That that sub-expression is a multiplication has no bearing on its order of evaluation relative to the other operand of the addition operation.
I understand that JLS guarantees that operands of a binary operation are evaluated left-to-right. But in my example in order to
understand method invocation sequence it is necessary to understand
which operation (and both its operands respectively!) is considered
first. Am I wrong here - why?
Yes, you are wrong, and JLS notwithstanding, your examples provide very good evidence for that.
The problem seems to be the "and both its operands respectively" bit. Your idea seems to be roughly that Java should look through the expression, find all the multiplication operations and fully evaluate them, including their operands, and only afterward go back and do the same for the addition operations. But that is not required to observe precedence, and it is not consistent with the left-to-right evaluation order of addition operations, and it would make Java code much harder for humans to write or read.
Let's consider your longer example:
int result = f1() + f2()*f3() + f4() + f5()*f6() + (f7()+f8());
Evaluation proceeds as follows:
f1()
is evaluated first, because it is the left operand of the first operation, and the the operation's operands must be evaluated left-to-right
f2()
is evaluated next, because it is part of the right operand to the addition (whose turn it is to be evaluated), and specifically the left operand of the multiplication
f3()
is evaluated next, because the multiplication sub-expression to which it belongs is being evaluated, and it is the right operand of that multiplication. Precedence affects the order of operations here by establishing that in fact it is the product that is being evaluated. If that were not so, then instead, the result of f2()
would be added to the result of f1()
at this point, before f3()
was computed.
- the product of
f2()
and f3()
is computed, in accordance with the precedence of multiplication over addition.
- The sum of (previously evaluated)
f1()
and f2()*f3()
is computed. This arises from a combination of precedence of *
over +
already discussed, and the left-to-right associativity of +
, which establishes that the sum is the left operand of the next addition operation, and therefore must be evaluated before that operation's right operand.
f4()
is evaluated, because it is the right operand of the addition operation being evaluated at that point.
- The second sum is computed. This is again because of the left-to-right associativity of
+
, and the left-to-right evaluation order of the next addition operation.
f5()
then f6()
then their product is evaluated. This is completely analogous to the case of f2()*f3()
, and thus is another exercise of operator precedence.
- the result of
f5()*f6()
, as the right-hand operand of an addition operation, is added to the left-hand operand. This is again analogous to previous steps.
f7()
is evaluated.
- Because of the parentheses,
f8()
is evaluated next, and then its sum with the previously-determined result of evaluating f7()
, and then that result is added to the preceding result to complete the computation. Without the parentheses, the order would be different: the result of f7()
would be added to the preceding result, then f8()
computed, then that result added.
f1()+f1()
won't be replaced with2*f1()
,3.0*x/4.0
won't be replace with(3.0/4.0)*x
, etc... – Wikiup