逻辑运算符 - 1

“嗨,阿米戈!”

“现在我们要上一堂关于逻辑运算符的小课。”

“你知道哪些逻辑运算符?”

— 或 (||)、与 (&&)、非 (!)

“是的。干得好。你还记得它们是如何工作的吗?”

“是的。”

“当至少有一个操作数为真时,或运算结果为真。”

“当两个操作数都为真时,AND 的结果为真。”

“不把真变假,把假变真。”

“没错。这个表达式中的运算符是按什么顺序求值的?”

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

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

“这一切都很简单。”

“首先是 NOT (!),然后是 AND (&&),最后是 OR (||)。”

如果我们添加括号,那么我们会得到:

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

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

“一切都正确,干得好。结果如何?”

— 1) (a && b) == (真 && 假) == 假

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

3) (!a) == 错误

4)假|| 假 || 假 == 假

“结果是假的。”

“看来你对这个话题了如指掌,那我告诉你两个小秘密。”

“首先,逻辑表达式是从左到右求值的。”

“其次,这里使用了短路求值(仅在必要时才进行计算)。如果通过对表达式的一部分求值已经知道最终结果,则不对表达式的其余部分求值。”

例子
boolean result = (true && false) || (true && true) || (true && false);

“此表达式分为三个部分,由 OR (||) 运算符分隔。”

“如果至少有一部分为真,则答案为真,无需考虑其他任何内容。因此,表达式的计算方式如下:”

1) 评估第一部分: (true && false) == false

2) 评估第二部分:  (true && true) == true

3)我们不评估第三部分,因为已经很清楚答案是true

“这种方法也称为惰性评估。”

“好吧。它有什么特别之处?”

“什么都没有——直到你开始调用表达式内部的方法。如果跳过了表达式的一部分,那么跳过的部分中的方法将不会被调用。”

“但这种方法已经变得非常普遍。原因如下:”

例子:
Job job = null;

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

“如果计算表达式时作业为空,则不会调用 job.isDone()!”

“事实上,表达式的第一部分是假的,后面是 AND (&&)。因此,整个表达式将被认为是假的,第二部分将不是必需的。”

“正是。这是一个很好的技术,对吧?”

“是的。”