&&(AND)和|| (或)在IF声明

我的问题可能是非常基本的,但我认为值得提问。 我有以下代码:

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

partialHits是一个HashMap。 如果第一个陈述是真的会发生什么? Java还会检查第二条语句吗? 因为为了使第一个语句成为true,HashMap不应该包含给定的键,所以如果第二个语句被选中,我将得到NullPointerException
所以简单地说,如果我们有下面的代码

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

如果在第一种情况下a是假的,如果a在第二种情况下是真的,Java会检查b

不,它不会被评估。 这是非常有用的。 就像你需要testing的那样,如果一个string不为空或空,你可以写:

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

或者相反

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

如果我们没有在Java中“短路”,我们会在上面的代码行中收到大量的NullPointerExceptionexception。

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

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

在检查参数的值之前,单个参数将检查每个参数,而不pipe其值如何。 双重的将首先检查左边的参数和它的值,如果是true|| )或false&& )则保持第二个参数不变。 声音完整? 一个简单的例子应该说清楚:

给出所有例子:

  String aString = null; 

和:

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

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

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

第一个参数被选中,返回false ,所以第二个参数不会被检查,因为结果是false的。

或者:

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

也会引发NullPointerException。

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

第一个参数被检查并返回true ,所以第二个参数不会被检查,因为结果是true

XOR不能被优化,因为它取决于两个参数。

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

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

条件15:23,条件 – 运算符(&&)说:

&&运算符与&(第15.22.2节)类似,但只有在其左侧操作数的值为true时,才会计算其右侧操作数。 在运行时,如果结果值为假,则条件expression式和值expression式的值为假,而右边的操作数expression式不计算。 如果左侧操作数的值为真,则右侧expression式将被计算,结果值将成为条件expression式的值。 因此,&&计算与布尔操作数上的&相同的结果。 它的区别仅在于右边的操作数expression式是有条件地而不是总是被评估的。

与此类似, Section 15:24,条件运算符(||)说:

|| 运算符就像| (第15.22.2节),但是只有在其左侧操作数的值为假时才计算其右侧操作数。 在运行时,首先评估左边的操作数expression式; 如果结果值为真,则条件或expression式的值为真,右边的操作数expression式不计算。 如果左侧操作数的值为假,则计算右侧expression式; 结果值变成条件或expression式的值。 因此,|| 计算与|相同的结果 布尔或布尔操作数。 它的区别仅在于右边的操作数expression式是有条件地而不是总是被评估的。

也许有点重复,但是确切地说,它们是如何工作的。 类似地,条件运算符(?:)仅评估适当的“half”(如果值为true,则为左半部分,如果为false,则为右半部分),从而允许使用如下expression式:

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

没有NullPointerException。

不,如果a是真的(在a ortesting中),b不会被testing,因为testing的结果总是是真的,不pipebexpression式的值是多less。

做一个简单的testing:

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

不会抛出一个NullPointerException

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

是的,布尔expression式的短路评估是所有类C系列中的默认行为。

一个有趣的事实是Java也使用&| 作为逻辑操作数(它们被重载,用inttypes它们是预期的按位操作)来评估expression式中的所有项,当你需要副作用时这也是有用的。

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

如果(A && B)如果A是假的,将导致短路。

如果(A && B) 不会导致短路,如果A是真的。

如果(A || B)会导致短路,如果A是真的。

如果(A || B) 不会导致短路如果A是假的。

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

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

 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); }