简体   繁体   中英

Why does this not short circuit?

public static void main(String args[]){
    String s = null;

    if(false && false || s.equalsIgnoreCase("x")) {    //throws an exception
        System.out.println("true");
    } else {
        System.out.println("false");
    }
}

I was expecting after this encounters false to short circuit but it doesn't. Why is that? I assumed if you have a false there is NO need to proceed to the next &&. Please help me to understand.

Because this:

a && b || c

is equivalent to this:

(a && b) || c

The lhs of the || is false, so c gets evaluated.

The && operator has higher precedence than the || operator . So, the condition is equivalent to

if( (false && false) || s.equalsIgnoreCase("x")) {    //throws an exception

which is then evaluated to leave:

if(false || s.equalsIgnoreCase("x")) {    //throws an exception

which doesn't short circuit. To make it short-circuit, use parentheses:

if(false && (false || s.equalsIgnoreCase("x"))) {    // fine

The and have higher precedence so it's bracketed like

((false && false) || s.equalsIgnoreCase("x"))

(false && false) reduces to false which is not short-circuit by || .


It's worth remembering that & is sort of like * ( 1 & 1 = 1 and 0 * 1 = 1 ) and + is sort of like | hence & have higher precedence. In maths sometimes + is used as or and nothing for both & and * . Logic operations have the same precedence as binary ones so && have higher then || .

Why should it short-circuit? || only short-circuits if the LH operand is true. && short-circuits if the LH operand is false. Here you have a short-circuing && and a non-short-circuiting ||.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM