Evaluation matches parentheses and precedence - java

According to the Java Language Specification:

Estimates match brackets and priorities

other than using a math operation like:

int i = 3;
int j =  3 * (9 + 3);
System.out.println(j); //results to 36

      

Are there other examples of this rule being applied? I tried to use

int i = 0;
int z = 0;
if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){
  System.out.println("Routed here");
}
System.out.println("i: " + i);
System.out.println("z: " + z);

      

but this results in i: 1 and z: 0. It looks like the if evaluation is still left to right.

+3


source to share


3 answers


The parentheses and precedence have nothing to do with the order in which expressions are evaluated at run time. That is, if you think that putting parentheses around an expression means that it will be evaluated earlier, or that a higher-priority operator is evaluated earlier, you are misunderstanding the concept.

Operator precedence answers the following questions: In the expression

a * b + c

      

Which operator does the compiler "bind" to arguments in the first place? If +

had a higher priority, he would have grabbed the arguments next to him before he *

could, so to speak; so the result is that b

and are added and the c

result is multiplied by a

. That is, it will be equivalent to

a * (b + c)

      

But in most programming languages ​​(with a few exceptions such as APL), it *

has a higher precedence. This means that the arguments are bound to *

before they are bound to +

, which means that a

both b

are multiplied and the result is appended to c

, that is

(a * b) + c

      

Similarly, in the expression



a + b * c

      

the result is that b

both c

are multiplied and the result is added to a

.

a + (b * c)

      

You can place round parts around expression parts to change how you bind arguments; so if you want to add a

and b

and multiply the sum by c

, you can say

(a + b) * c

      

But it's very important to note: this all determines how the expression is interpreted at compile time. But at run time, arguments are always evaluated from left to right. When the program starts, ALL of the above expressions will cause the program to evaluate a

, then b

, then c

.
It doesn't matter if a

, b

and c

are variables, but if they were a method call, it might matter. In Java, when a program starts up, things are always evaluated from left to right. (This is not the case for other languages; most languages ​​I know of allow the compiler to choose the order.)

And when it comes to ||

and &&

(or similar operators in some other languages), once again at runtime, the left argument is always evaluated first . A correct argument may or may not be appreciated. Parentheses and operator precedence control how an expression is interpreted when you have a type expression some-expression-1 || some-expression-2 && some-expression-3

, but they do not change the order of evaluation at runtime.

+2


source


Since ||

Java uses the concept of short-circuiting when evaluating expressions. So in this:

if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){

      

since the first expression i++ < 5

returns true, so the rest of the expression will not be evaluated, i.e. will never be visited, therefore, will only change the meaning i

and no other thing.



Quoting from Java Docs:

Conditional operators && and || operators perform conditional-AND and conditional-OR operations on two boolean expressions. These operators exhibit "short-circuiting" behavior, which means that the second operand is evaluated only when necessary. && Conditional-AND || Conditional OR The following program, ConditionalDemo1, tests these operators:
class ConditionalDemo1 {

    public static void main(String[] args){
        int value1 = 1;
        int value2 = 2;
        if((value1 == 1) && (value2 == 2))
            System.out.println("value1 is 1 AND value2 is 2");
        if((value1 == 1) || (value2 == 1))
            System.out.println("value1 is 1 OR value2 is 1");
    }
}

      

+5


source


Once the test can evaluate to true or false, execution is performed in the if block. In your case, i

is equal 0

, which is less than 5

, so the test evaluates to true

.

(true OR a OR b)

is true regardless of values a

and b

that are not evaluated (and no increments are applied).

Would be the same with (false AND a AND b)

, except he always skipped a block.

Check the order of your expressions, split them into separate tests, or get your increments from a test. The following code is equivalent to your example, but with the expected result:

int i = 0;
int z = 1;
if(i < 5 || (z < 0 && 5 > z+2) || 6 < i+2){
  System.out.println("Routed here");
}
i += 2;
z += 2;
System.out.println("i: " + i);
System.out.println("z: " + z);

      

+1


source







All Articles