前面讲了比较运算符,比较计算结果为布尔值,经常用在分支和循环语句中。为了让分支和循环的条件判断更有趣,可以使用逻辑运算符把多个比较表达式合并成一个更复杂的表达式。逻辑运算符的操作数必须是布尔值,而且计算结果也是布尔值。逻辑运算符有如下几个:
条件与(&&)
条件或(||)
逻辑非(!)
逻辑与(&)
逻辑或(|)
逻辑异或(^)
下面分别进行说明。
条件与(&&)
这个运算符对操作数执行逻辑与运算。仅当两个操作数都是 true 时才返回 true;如果有一个或两个操作数都是 false,计算结果为 false。例如:
if (x < 10 && y > 3) ... // 如果两个比较表达式的结果都是true
这个运算符(以及除了一元运算符 ! 之外的所有逻辑运算符)的优先级没有比较运算符高,因此完全可以编写类似上面的代码。不过,有些程序员倾向于使用括号,明确表明计算的顺序:
if ((x < 10) && (y > 3))...
你觉得哪种写法更易读就用哪种。
这个运算符之所以叫条件与,是因为它会视情况决定是否计算第二个操作数。如果第一个操作数的结算结果为 false,不管第二个操作数的计算结果是什么,这个表达式的计算结果都是 false。因此,为了提高效率,Java 解释器会走捷径,跳过第二个操作数。因为不一定会计算第二个操作数,所以使用这个运算符时,如果表达式有副作用,一定要注意。不过,因为有这种特性,可以使用这个运算符编写如下的 Java 表达式:
if (data != null && i < data.length && data[i] != -1) ...
如果第一个和第二个比较表达式的计算结果为 false,第二个和第三个比较表达式会导致错误。幸好,我们无需为此担心,因为 && 运算符会视情况决定是否执行后面的表达式。
条件或(||)
这个运算符在两个布尔值操作数上执行逻辑或运算。如果其中一个或两个都是 true,计算结果为 true;如果两个操作数都是 false,计算结果为 false。和 && 运算符一样,|| 并不总会计算第二个操作数。如果第一个操作数的计算结果为 true,不管第二个操作数的计算结果是什么,表达式的计算结果都是 true。因此,遇到这种情况时,|| 运算符会跳过第二个操作数。
逻辑非(!)
这个运算符改变操作数的布尔值。如果应用于 true,计算结果为 false;如果应用于false,计算结果为 true。在下面这种表达式中很有用:
if (!found) ... // found是其他地方定义的布尔值
while (!c.isEmpty()) ... // isEmpty()方法返回布尔值
! 是一元运算符,优先级高,经常必须使用括号:
if (!(x > y && y > z))
逻辑与(&)
如果操作数是布尔值,& 运算符的行为和 && 运算符类似,但是不管第一个操作数的计算结果如何,总会计算第二个操作数。不过,这个运算符几乎都用作位运算符,处理整数操作数。很多 Java 程序员都认为使用这个运算符处理布尔值操作数是不合法的 Java代码。
逻辑或(|)
这个运算符在两个布尔值操作数上执行逻辑或运算,和 || 运算符类似,但是就算第一个操作数的计算结果为 true,也会计算第二个操作数。| 运算符几乎都用作位运算符,处理整数操作数,很少用来处理布尔值操作数。
逻辑异或(^)
如果操作数是布尔值,这个运算符的计算结果是两个操作数的异或。如果两个操作数中只有一个是 true,计算结果才是 true。也就是说,如果两个操作数都是 true 或 false,计算结果为 false。这个运算符与 && 和 || 不同,始终会计算两个操作数。^ 运算符更常用作位运算符,处理整数操作数。如果操作数是布尔值,这个运算符等效于 != 运算符。