Sometimes you know that something is true without taking the time to
figure out all of the details. For instance, if someone says to you, "I
will go out for a run if the sun is shining or ...", it doesn't really
matter what comes after the OR as long as you know the sun is
shining. A Java program does the same thing. It can often figure out if
an expression will be true
or false
without
evaluating the entire expression. It takes a short-cut, called
"short-circuit evaluation," to arrive at the same answer.
Opportunities for short-circuit evalution are apparent from the truth
tables examined in the previous lab exercise. When two expressions are
joined by OR (||
), if the first one is true
,
the answer will always be true
. When two expressions are
joined by AND (&&
), if the first one is
false
, the answer will aways be false
. It
doesn't matter what the second expression is and hence, it doesn't need to
be evaluated.
|
|
Open project.jpr
, found in the Booleans
folder that you downloaded earlier. The main
method
contains
public static void main(String[] args) { ShortCircuitTest sct = new ShortCircuitTest(); if (sct.isTrue("left") && sct.isTrue("right")) { System.out.println("Expression is true."); } else { System.out.println("Expression is false."); } System.out.println("All done."); }
isTrue
is a predicate that always returns
true
. This is pretty useless except that it also prints out
it's argument, "left"
or "right"
, when it is
called. We can use this to understand short-circuit evaluation more
thoroughly. The definition of isTrue
is
public boolean isTrue(String msg) { System.out.println("in isTrue (arg = '" + msg + "')"); return true; }
When this program is run (do it!), it prints out
in isTrue (arg = 'left') in isTrue (arg = 'right') Expression is true. All done.
This shows that to evaluate the if
statement, both the
expression on the left of the &&
and the expression
on the right were evaluated.
Now change the left-most isTrue
to
isFalse
in the if
statement. It should now read
if(sct.isFalse("left") && sct.isTrue("right"))Run the program. What is the output?
Add the following code to the end of the main
method,
along with import java.util.ArrayList;
at the beginning of
the file:
ArrayList aList = new ArrayList(); aList.add("Cobol"); aList.add("Pascal"); aList.add("Java"); aList.add("Cobol"); aList.add("Basic"); aList.add("Java"); // find first position containing "Java" int pos = 0; while (!aList.get(pos).equals("Java")) // while we haven't found "Java" { pos++; } System.out.println("'Java' is at position " + pos);
Run the program. It should print out 'Java' is at position
2.
Now, remove both lines adding
Java
to the ArrayList
. Re-run the
program. You'll get a nasty exception because the while
loop
tried to access an invalid position in the ArrayList
. The
while loop should only continue if we haven't yet found the string
we're looking for AND we haven't reached the end of the
ArrayList
.
Do the following:
if (pos < aList.size()) { System.out.println("'Java' is at position " + pos); } else { System.out.println("'Java' is not in the ArrayList."); }
while
loop so that if
pos
is beyond the end of the ArrayList
,
the test for equality with Java
is not
performed because of short-circuit evaluation. (Hint: Your new
test should also use the size
method.)while
loop?