Java's "&&" vs "&" operator

124 views Asked by At

I am using the example from Java the complete reference by Herbert Schildt, 12th ed and Java is 14

Where he gives the 2 following examples (if blocks), the first one is ok and the 2nd one is wrong therefore commented

public class PatternMatch {
    public static void main(String[] args){
        Number myOb = Integer.valueOf(9);
        int count = 10;
        if((count < 100) && myOb instanceof Integer iObj) { // is OK!!!
            iObj = count;
        }

        /*
        if((count < 100) & myOb instanceof Integer iObj) { // Error!!!
            iObj = count;
        }
        */
    }
}

His explanation on why the 2nd if block (commented out) is "In this case, the compiler cannot know whether or not iObj will be in scope in the if block because the right side of the & will not necessarily be evaluated". This leads to my confusion: & makes sure both its left and right sides are ALWAYS evaluated so why "because the right side of the & will not necessarily be evaluated"?

Thanks!

if you put the java14 code in your IDE, you do see the 2nd if block produces the compilation error saying iObj not defined... but I just don't understand his explanation:

His explanation on why the 2nd if block is "In this case, the compiler cannot know whether or not iObj will be in scope in the if block because the right side of the & will not necessarily be evaluated". This leads to my confusion: & makes sure both its left and right sides are ALWAYS evaluated so why "because the right side of the & will not necessarily be evaluated"?

public class PatternMatch {
    public static void main(String[] args){
        Number myOb = Integer.valueOf(9);
        int count = 10;
        if((count < 100) && myOb instanceof Integer iObj) { // is OK!!!
            iObj = count;
        }

    
        if((count < 100) & myOb instanceof Integer iObj) { // Error!!!
            iObj = count;
        }
   
    }
}
1

There are 1 answers

8
rzwitserloot On

Indeed, 'right side will not necessarily be evaluated' is just completely wrong.

&& is legal because within the if statement, you have an absolute guarantee that myObj instanceof Integer iObj will have been evaluated, and evaluated to true (thus establishing iObj in the scope of the code inside the if block). Given a && b, b is not neccessarily evaluated, but if code flows into that if, b definitely has been, which is why your first snippet compiles.

& is presumably not legal here because the spec didn't bother. There is no explanation that involves a scenario where myObj instanceof Integer iObj either didn't get evaluated, or evaluated to false somehow. Inside the if block, it will have been evaluated, and will have evaluated to true. But, the point is, the compiler has to figure out that based on static code analysis and that part is where the spec doesn't bother listing out explicitly that boolean & boolean establishes definite evaluation (and definitely true evaluation).