Logical operators - 1

"Hi, Amigo!"

"Now we'll have a small lesson on logical operators."

"What logical operators do you know?"

— OR (||), AND (&&), NOT(!)

"Yep. Good job. And do you remember how they work?"

"Yes."

"OR yields true when at least one operand is true."

"AND yields true when both operands are true."

"NOT changes true to false, and false to true."

"That's right. And in what order are the operators evaluated in this expression?"

boolean a = true;
boolean b = false;
boolean c = true;

boolean result = a && b || !c && b || !a;

"This is all very simple."

"First, NOT (!), then AND (&&), and then OR (||) at the very end."

If we added parentheses, then we would get:

boolean a = true;
boolean b = false;
boolean c = true;

boolean result = (a && b) || ((!c) && b) || (!a);

"That's all correct, well done. And what is the result?"

— 1) (a && b) == (true && false) == false

2) ((!c) && b) == (false && false) == false

3) (!a) == false

4) false || false || false == false

"The result is false."

"It seems you know the topic perfectly. Then I'll tell you a couple of little secrets."

"First, logical expressions are evaluated from left to right."

"Second, short-circuit evaluation is used here (calculations are performed only if necessary). If the final result is already known from evaluating part of the expression, then the rest of the expression is not evaluated."

Example
boolean result = (true && false) || (true && true) || (true && false);

"This expression is divided into three parts separated by the OR (||) operator."

"If at least one part is true, then the answer is true and nothing else needs to be considered. Accordingly, the expression is evaluated like this:"

1) Evaluate the first part:  (true && false) == false

2) Evaluate the second part: (true && true) == true

3) We don't evaluate the third part, since it is already clear that the answer will be true.

"This approach is also called lazy evaluation."

"OK. And what's so special about it?"

"Nothing—until you start calling methods inside the expression. If part of the expression is skipped, then the methods in the skipped part will not be called."

"But this approach has become very common. Here's why:"

Example:
Job job = null;

if (job != null && job.isDone())
{
…
}

"If job is null when the expression is evaluated, then the job.isDone() call won't happen!"

"Indeed, the first part of the expression is false, which is followed by AND (&&). So, the entire expression will be known to be false, and the second part won't be necessary."

"Exactly. It's a good technique, right?"

"Yep."