在Java的if块中使用逻辑运算符和位运算符有什么区别吗?

14

以下两个if块的内容都应该被执行:

if( booleanFunction() || otherBooleanFunction() ) {...}
if( booleanFunction() | otherBooleanFunction() ) {...}

那么使用 | 和使用 || 有什么区别呢?

注:我已经查过了并找到了自己的答案,我在下面附上了。请随意纠正我或提出您自己的看法。肯定还有改进的空间!


1
我不明白这个问题的意义,你问一个问题然后自己回答 - 在任何人回答之前? - Nim
10
@Nim和Durandal:嗯...我可能没有理解到点子上,但是根据this的内容,如果你认为自己的问题对其他人有用,回答自己的问题实际上是可以的。我解决了自己的问题,想分享一下,所以我费劲地在这里记录了它。并不是有意冒犯任何人。 - Miquel
@Miquel,这不是关于冒犯的问题,我认为问题在于你立即回答了问题,这给人一种你试图向怀疑论者(比如我自己!:))刷声望的印象。下次请花点时间看看社区的回答,如果你找不到合适的答案,请做出贡献——这样就可以消除任何这样的印象了…… - Nim
@Nim 好的,我明白了。显然这被误解了,所以我将按照你的建议在未来做,同时我会将讨论移到元数据上。也许我们不应该直接在发布问题的框下面放置“回答自己的问题”。 - Miquel
7
我不明白这有什么大不了的。也许米格尔没有整天等待完成他想要完成的事情。如果我处于那种情况并且已经有了足够的解决方案回答我的问题,我也不会为了面子而等待。 - Stack Underflow
5个回答

40

这两者有不同的用途。尽管在许多情况下(处理布尔值时)它们可能具有相同的效果,但重要的是要注意逻辑OR是短路操作,这意味着如果其第一个参数求值为true,则第二个参数将被留未求值。位运算符则会评估其两个参数。

类似地,逻辑AND也是短路操作,这意味着如果其第一个参数求值为false,则第二个参数将被留未求值。位运算符则不是。

您可以在此处查看其效果:

int x = 0;
int y = 1;
System.out.println(x+y == 1 || y/x == 1);
System.out.println(x+y == 1 |  y/x == 1);

第一个打印语句能够正常工作并且返回true,因为第一个参数的计算结果为true,所以计算停止。第二个打印语句出错了,因为它不是短路运算,会遇到除以零的情况。


15

逻辑运算符用于布尔类型,位运算符用于比特类型。在这种情况下,效果将是相同的,但有两个区别:

  1. 位运算符不是为此而设计的,这使得代码难以阅读,但最重要的是
  2. 逻辑 OR 运算符将评估第一个条件。如果它为 true,则无论下一个条件的结果如何,结果都将为 true,因此 第二个子句不会执行

以下是一些方便的代码来证明这一点:

public class OperatorTest {

    public static void main(String[] args){
        System.out.println("Logical Operator:");
        if(sayAndReturn(true, "first") || sayAndReturn(true, "second")){
            //doNothing
        }

        System.out.println("Bitwise Operator:");
        if(sayAndReturn(true, "first") | sayAndReturn(true, "second")){
            //doNothing
        }
    }

    public static boolean sayAndReturn(boolean ret, String msg){
        System.out.println(msg);
        return ret;
    }
}

在if语句中,&运算符有实际的用途吗? - eaglei22
1
使用它的唯一理由就是让两个子句都执行作为副作用,而我认为这是一个非常糟糕的想法,因为你可能不应该首先在if语句中依赖副作用,并且很容易误读。 - Miquel

7

对于程序员来说,只有一个区别。

  1. 逻辑运算符是逻辑的,即它们仅测试一个条件,并基于该条件得出结果。

booleanFunction() || otherBooleanFunction() 如果其中任意一个为true,则为true。同样地,booleanFunction() && otherBooleanFunction() 如果其中任意一个为false,则为false。因此,为什么要测试另一个呢?这就是逻辑运算符的作用。

但是按位运算符检查两个条件。这个概念的一个常见应用是:

if(someObject != null && someObject.somemethod())

所以,在这种情况下如果你用&代替&&,那么你将等待一场灾难。不久你会遇到讨厌的NullPointerException错误...

4
if( booleanFunction() || otherBooleanFunction() ) {...}

在这种情况下,如果 booleanFunction() 返回 true,则不会执行 otherBooleanFunction()
if( booleanFunction() | otherBooleanFunction() ) {...}

但在位运算符中,无论booleanFunction()返回true还是false,两个函数booleanFunction()otherBooleanFunction()都将被执行。


0
位运算符和逻辑运算符的区别: 1. 位运算符作用于位,而逻辑运算符作用于语句。 2. 按位与由&表示,而逻辑与由&&表示。 3. 按位或由|表示,而逻辑或由||表示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接