
“嗨,阿米戈!”
“现在我们要上一堂关于逻辑运算符的小课。”
“你知道哪些逻辑运算符?”
— 或 (||)、与 (&&)、非 (!)
“是的。干得好。你还记得它们是如何工作的吗?”
“是的。”
“当至少有一个操作数为真时,或运算结果为真。”
“当两个操作数都为真时,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 (&&)。因此,整个表达式将被认为是假的,第二部分将不是必需的。”
“正是。这是一个很好的技术,对吧?”
“是的。”
GO TO FULL VERSION