2

Currently I'm working on a program which has a memory intense checking process. At some point the code looks like this.

if(isvalid() && false) //this false is acctually another method which will at this given 
                       //point always return false
{
    //rest ommited
}

Will the JVM always check the first method (isValid()) or not since x && false is aways false;

I am not sure because while debugging the debugger is jumping to isValid() method at every iteration.

ZeDonDino
  • 5,072
  • 8
  • 27
  • 28
  • 3
    See http://stackoverflow.com/questions/8759868/java-logcial-operators-short-circuiting and http://stackoverflow.com/questions/7101992/why-do-we-usually-use-not-what-is-the-difference for more information about short circuit operations. – Paul Tomblin Aug 17 '13 at 15:24
  • What does your Java language reference say?? – Hot Licks Aug 18 '13 at 13:58

4 Answers4

9

It will always check isValid(). The sematics of && is to evaluate the left part and only if it is true look at the right part.

Henry
  • 42,982
  • 7
  • 68
  • 84
3

The JVM always evaluates the left side of the && or || first, and then only evaluates the right side if necessary. If you think the operation on the right of an && is more likely to return false, then you should switch them around and put it first.

More details: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.23

At run time, the left-hand operand expression is evaluated first; if the result has type Boolean, it is subjected to unboxing conversion (§5.1.8).

If the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated.

Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • 1
    No, one should only switch the operations around to put the *less expensive* test on the left (unless one of the tests *must* go first to "guard" the other). Of course, "less expensive" must take into account the probabilities of true/false. If A is false 25% of the time and B is false 100% of the time, A should go first if the time required to evaluate A is less than 1/4 of the time required to evaluate B. – Hot Licks Aug 18 '13 at 14:02
0

If you look inside bytecode, generated by JDK, you`ll notice that if block content t is omitted.

if(isValid() && false){
    System.out.print("qqq");
}
System.out.print("www");

bytecode:

0: invokestatic  #2                  // Method isValid:()Z
3: ifeq          6                  // no if block content!!!
6: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
9: ldc           #4                  // String www
11: invokevirtual #5                  // Method java/io/PrintStream.print:(Ljava/lang/String;)V

Method will be called, but with no effect on branch logic.

Mikhail
  • 4,175
  • 15
  • 31
0
public static void main(String[] args) {

    Stack<Boolean> nums = new Stack<>();
    nums.push(true);
    System.out.println(nums.pop() && false);
    System.out.println(nums.isEmpty());

    nums.push(true);
    System.out.println(false && nums.pop());
    System.out.println(nums.isEmpty());
}

it prints false true false false

you should be careful when use false && or ture || in your code,sometimes 为 will not use like this case,but the following case we maybe use;

public static void main(String[] args) {

    Stack<Boolean> nums = new Stack<>();
    nums.push(true);
    nums.push(false);
    System.out.println(nums.pop() && nums.pop());
    System.out.println(nums.isEmpty());

}

it prints false false

yuanopen
  • 1
  • 2