I'm trying to figure out how operator precedence and the short-circuit feature of && and || are combined. Specifically, since && and || have low precedence (table from Oracle here; I couldn't find a operator precedence table in the language spec itself) then it seems like Java programs should evaluate the left/right sides before doing the &&/||. For example:
1 < 3 || 2 < 3
the above code should first evaluate "1 < 3" (and get 'true'), then the next-highest operator is the remaining '<' so Java evaluates 2 < 3 (also 'true'), and then finally the lowest-precedence operator || is evaluated.
Of course, we know that this isn't what happens.
Instead, the left sub-expression is evaluated, 1 < 3 evaluates to 'true', and the logical OR short-circuits and doesn't even evaluate the right side of the expression. One can write code that causes side effects (such as printing messages when a function is called) to verify this - any methods on the right side aren't run at all.
This seems to contradict the operator precedence rules - the comparison operators should go before the logical AND.
How is this contradiction resolved? When, exactly, does && get evaluated?
Informally, it seems like the Java program must be set up so that it first scans the entire expression, finds any &&s or ||s, finds the 'subexpressions' to the left & right of the &&s and ||s, and then ignores the precedence table for anything in either subexpression. Once enough of the overall expression has been evaluated and Java needs the result of the subexpressions joined by && or || then it'll evaluate the left subexpression first (recursively applying the precedence rules within the left subexpression), and then use that result to figure out if it needs to evaluate the right subexpression.
Is this correct?
And for bonus points, where does it specify this in the Java language spec?