Java && (AND) 和 || (OR) 在 IF 语句中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1795808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:44:37  来源:igfitidea点击:

&& (AND) and || (OR) in IF statements

javaif-statement

提问by Azimuth

I have the following code:

我有以下代码:

if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){  
    partialHits.get(z).put(z, tmpmap.get(z));  
}

where partialHitsis a HashMap.
What will happen if the first statement is true?Will Java still check the second statement?Because in order the first statement to be true, the HashMap should not contain the given key, so if the second statement is checked, I will get NullPointerException.
So in simple words, if we have the following code

哪里partialHits是 HashMap。
如果第一个陈述为真,会发生什么?Java 还会检查第二个语句吗?因为为了让第一条语句为真,HashMap 不应该包含给定的键,所以如果检查第二条语句,我会得到NullPointerException.
所以简单来说,如果我们有以下代码

if(a && b)  
if(a || b)

would Java check bif ais false in the first case and if ais true in the second case?

Java 会检查在第一种情况下b是否a为假,a在第二种情况下是否为真?

采纳答案by Andreas Dolk

No, it will not be evaluated. And this is very useful. For example, if you need to test whether a String is not null or empty, you can write:

不,它不会被评估。这是非常有用的。例如,如果您需要测试一个 String 是否不为 null 或为空,则可以编写:

if (str != null && !str.isEmpty()) {
  doSomethingWith(str.charAt(0));
}

or, the other way around

或者,反过来

if (str == null || str.isEmpty()) {
  complainAboutUnusableString();
} else {
  doSomethingWith(str.charAt(0));
}

If we didn't have 'short-circuits' in Java, we'd receive a lot of NullPointerExceptions in the above lines of code.

如果我们在 Java 中没有“短路”,我们就会在上面的代码行中收到很多 NullPointerExceptions。

回答by Peter van der Heijden

No it will not be checked. This behaviour is called short-circuit evaluationand is a feature in many languages including Java.

不,它不会被检查。这种行为称为短路评估,是包括 Java 在内的许多语言的一个特性。

回答by Romain Linsolas

No, if a is true (in a ortest), b will not be tested, as the result of the test will always be true, whatever is the value of the b expression.

不,如果 a 为真(在or测试中),则不会测试 b,因为测试的结果将始终为真,无论 b 表达式的值是多少。

Make a simple test:

做一个简单的测试:

if (true || ((String) null).equals("foobar")) {
    ...
}

will notthrow a NullPointerException!

不会NullPointerException

回答by abyx

No it won't, Java will short-circuit and stop evaluating once it knows the result.

不,它不会,Java 一旦知道结果就会短路并停止评估。

回答by Cowan

All the answers here are great but, just to illustrate where this comes from, for questions like this it's good to go to the source: the Java Language Specification.

这里的所有答案都很好,但是,为了说明这是从哪里来的,对于这样的问题,最好转到源代码:Java 语言规范。

Section 15:23, Conditional-And operator (&&), says:

第 15:23 节,条件与运算符 (&&)说:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true. [...] At run time, the left-hand operand expression is evaluated first [...] if the resulting value is false, the value of the conditional-and expression is false and the right-hand operand expression is not evaluated. If the value of the left-hand operand is true, then the right-hand expression is evaluated [...] the resulting value becomes the value of the conditional-and expression. Thus, && computes the same result as & on boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

&& 运算符类似于 &(第 15.22.2 节),但仅当其左侧操作数的值为真时才计算其右侧操作数。[...] 在运行时,首先评估左侧操作数表达式 [...] 如果结果值为 false,则条件和表达式的值为 false 且不评估右侧操作数表达式. 如果左侧操作数的值为真,则对右侧表达式求值 [...] 结果值成为条件与表达式的值。因此, && 在布尔操作数上计算与 & 相同的结果。它的不同之处仅在于右侧操作数表达式是有条件地而不是始终进行计算的。

And similarly, Section 15:24, Conditional-Or operator (||), says:

同样,第 15:24 节,条件或运算符 (||)说:

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false. [...] At run time, the left-hand operand expression is evaluated first; [...] if the resulting value is true, the value of the conditional-or expression is true and the right-hand operand expression is not evaluated. If the value of the left-hand operand is false, then the right-hand expression is evaluated; [...] the resulting value becomes the value of the conditional-or expression. Thus, || computes the same result as | on boolean or Boolean operands. It differs only in that the right-hand operand expression is evaluated conditionally rather than always.

|| 运算符就像 | (第 15.22.2 节),但仅当其左侧操作数的值为 false 时才评估其右侧操作数。[...] 在运行时,首先评估左侧操作数表达式;[...] 如果结果值为真,则条件或表达式的值为真,并且不计算右侧操作数表达式。如果左侧操作数的值为假,则评估右侧表达式;[...] 结果值成为条件或表达式的值。因此,|| 计算与 | 相同的结果 在布尔或布尔操作数上。它的不同之处仅在于右侧操作数表达式是有条件地而不是始终进行计算的。

A little repetitive, maybe, but the best confirmation of exactly how they work. Similarly the conditional operator (?:) only evaluates the appropriate 'half' (left half if the value is true, right half if it's false), allowing the use of expressions like:

可能有点重复,但最好确认它们的工作方式。类似地,条件运算符 (?:) 只计算适当的“一半”(如果值为真则为左半,如果值为假则为右半),允许使用以下表达式:

int x = (y == null) ? 0 : y.getFoo();

without a NullPointerException.

没有 NullPointerException。

回答by fortran

Yes, the short-circuit evaluation for boolean expressions is the default behaviour in all the C-like family.

是的,布尔表达式的短路评估是所有类 C 家族的默认行为。

An interesting fact is that Java also uses the &and |as logic operands (they are overloaded, with inttypes they are the expected bitwise operations) to evaluate all the terms in the expression, which is also useful when you need the side-effects.

一个有趣的事实是,Java 还使用&and|作为逻辑操作数(它们是重载的,int它们的类型是预期的按位运算)来计算表达式中的所有项,这在您需要副作用时也很有用。

回答by Hardcoded

Java has 5 different boolean compare operators: &, &&, |, ||, ^

Java 有 5 种不同的布尔比较运算符:&、&&、|、||、^

& and && are "and" operators, | and || "or" operators, ^ is "xor"

& 和 && 是“与”运算符,| 和 || “或”运算符,^ 是“异或”

The single ones will check every parameter, regardless of the values, before checking the values of the parameters. The double ones will first check the left parameter and its value and if true(||) or false(&&) leave the second one untouched. Sound compilcated? An easy example should make it clear:

在检查参数值之前,单个参数将检查每个参数,而不管其值如何。double 将首先检查 left 参数及其值,如果true( ||) 或false( &&) 保持第二个不变。声音复杂?一个简单的例子应该清楚地说明:

Given for all examples:

给出所有示例:

 String aString = null;

AND:

和:

 if (aString != null & aString.equals("lala"))

Both parameters are checked before the evaluation is done and a NullPointerException will be thrown for the second parameter.

在评估完成之前检查这两个参数,并且将为第二个参数抛出 NullPointerException。

 if (aString != null && aString.equals("lala"))

The first parameter is checked and it returns false, so the second paramter won't be checked, because the result is falseanyway.

检查第一个参数并返回false,因此不会检查第二个参数,因为false无论如何结果。

The same for OR:

OR 也一样:

 if (aString == null | !aString.equals("lala"))

Will raise NullPointerException, too.

也会引发 NullPointerException。

 if (aString == null || !aString.equals("lala"))

The first parameter is checked and it returns true, so the second paramter won't be checked, because the result is trueanyway.

检查第一个参数并返回true,因此不会检查第二个参数,因为true无论如何结果。

XOR can't be optimized, because it depends on both parameters.

XOR 无法优化,因为它取决于两个参数。

回答by Peter Lawrey

This goes back to the basic difference between & and &&, | and ||

这又回到了&和&&的基本区别,| 和 ||

BTW you perform the same tasks many times. Not sure if efficiency is an issue. You could remove some of the duplication.

顺便说一句,您多次执行相同的任务。不确定效率是否是一个问题。您可以删除一些重复项。

Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){   
    partialHits.get(z).put(z, z3);   
} 

回答by user3211238

Short circuit here means that the second condition won't be evaluated.

这里的短路意味着不会评估第二个条件。

If ( A && B ) will result in short circuit if A is False.

If ( A && B ) 如果 A 为 False 将导致短路。

If ( A && B ) will notresult in short Circuit if A is True.

If ( A && B )如果 A 为真,则不会导致短路。

If ( A || B ) will result in short circuit if A is True.

If ( A || B ) 如果 A 为 True 将导致短路。

If ( A || B ) will notresult in short circuit if A is False.

If ( A || B )如果 A 为假,则不会导致短路。