我只是想知道为什么我们通常在两个布尔值之间使用逻辑OR ||,而不是按位或|,尽管它们都工作得很好。
我的意思是,看看下面这些:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
我们可以用|代替||吗?&和&&也是一样。
有很多用例表明为什么你应该选择||而不是|。有些用例必须使用|操作符来检查所有条件。
例如,如果您希望检查表单验证,并且希望向用户显示所有带有错误文本的无效字段,而不仅仅是第一个无效字段。
||算子是,
if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
private boolean checkIfEmpty(Widget field) {
if(field.isEmpty()) {
field.setErrorMessage("Should not be empty!");
return true;
}
return false;
}
因此,在上面的代码片段中,如果用户提交的表单中所有字段都是空的,那么只有nameField将显示错误消息。但是,如果你把它改成,
if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
无论真实情况如何,它都会在每个字段上显示正确的错误信息。
1).(expression1 | expression2), |运算符将计算expression2,而不管expression1的结果是真还是假。
例子:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b | test());
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
2).(expression1 || expression2),如果expression1为真,||操作符将不计算expression2。
例子:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b || test())
{
System.out.println("short circuit!");
}
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
除了短路之外,另一件需要记住的事情是,对可能不是0或1的值执行位逻辑操作与条件逻辑具有非常不同的含义。虽然|和||通常是一样的,但使用&和&&你会得到非常不同的结果(例如2 & 4是0/假,而2 && 4是1/真)。
如果你从一个函数中得到的东西实际上是一个错误代码,而你正在测试非0,这可能会很重要。
在Java中,这不是一个大问题,因为你必须显式地将类型转换为布尔值或与0进行比较,但在其他具有类似语法的语言(C/ c++等)中,这可能相当令人困惑。
另外,请注意&和|只能应用于整数类型的值,而不是所有可以等效于布尔测试的值。同样,在非java语言中,有相当多的东西可以用作带有隐式!= 0比较的布尔值(指针、浮点数、带有操作符bool()的对象等),而位操作符在这些上下文中几乎总是毫无意义的。
如果使用||和&&形式,而不是这些操作符的|和&形式,Java将不会费心单独计算右操作数。
这是一个你是否想要缩短评估的问题——大多数时候你想这样做。
说明短路的好处的一个好方法是考虑下面的例子。
Boolean b = true;
if(b || foo.timeConsumingCall())
{
//we entered without calling timeConsumingCall()
}
正如Jeremy和Peter提到的,短路的另一个好处是空引用检查:
if(string != null && string.isEmpty())
{
//we check for string being null before calling isEmpty()
}
更多信息