逻辑操作符 “与”(&&)、“或”(||)和 “非”(!)可以根据参数的逻辑关系,生成一个 true 或 false 的布尔值结果。下面这个示例就使用了关系操作符和逻辑操作符。
// operators/Bool.java
// 关系操作符和逻辑操作符
import java.util.*;
public class Bool {
public static void main(String[] args) {
Random rand = new Random(47);
int i = rand.nextInt(100);
int j = rand.nextInt(100);
System.out.println("i = " + i);
System.out.println("j = " + j);
System.out.println("i > j is " + (i > j));
System.out.println("i < j is " + (i < j));
System.out.println("i >= j is " + (i >= j));
System.out.println("i <= j is " + (i <= j));
System.out.println("i == j is " + (i == j));
System.out.println("i != j is " + (i != j));
// 在Java中,把int类型当作boolean类型并不合法:
//- System.out.println("i && j is " + (i && j));
//- System.out.println("i || j is " + (i || j));
//- System.out.println("!i is " + !i);
System.out.println("(i < 10) && (j < 10) is "
+ ((i < 10) && (j < 10)) );
System.out.println("(i < 10) || (j < 10) is "
+ ((i < 10) || (j < 10)) );
}
}
/* 输出:
i = 58
j = 55
i > j is true
i < j is false
i >= j is true
i <= j is false
i == j is false
i != j is true
(i < 10) && (j < 10) is false
(i < 10) || (j < 10) is false
*/
“与” “或” “非” 操作只可应用于布尔值。你不能像 C 及 C++ 中那样,在逻辑表达式中将一个非布尔值当作布尔值使用。代码里用//-注释掉的语句就是这种错误的尝试。后面的表达式先使用关系比较操作符来生成布尔值结果,然后再对生成的布尔值进行逻辑运算。
注意,如果在应该使用字符串的地方使用了布尔值,布尔值会自动转换成合适的文本格式。
在前面的程序中,你可将 int 类型替换成除 boolean 类型外的其他任何基本数据类型。
短路
逻辑操作符支持一种称为“短路”的现象。一旦表达式当前部分的计算结果能够明确无误地确定整个表达式的值,表达式余下部分就不会被执行了。因此,逻辑表达式后面的部分有可能不被执行。下面是演示短路现象的示例:
// operators/ShortCircuit.java
// 逻辑表达式中的短路现象
public class ShortCircuit {
static boolean test1(int val) {
System.out.println("test1(" + val + ")");
System.out.println("result: " + (val < 1));
return val < 1;
}
static boolean test2(int val) {
System.out.println("test2(" + val + ")");
System.out.println("result: " + (val < 2));
return val < 2;
}
static boolean test3(int val) {
System.out.println("test3(" + val + ")");
System.out.println("result: " + (val < 3));
return val < 3;
}
public static void main(String[] args) {
boolean b = test1(0) && test2(2) && test3(2);
System.out.println("expression is " + b);
}
}
/* 输出:
test1(0)
result: true
test2(2)
result: false
expression is false
*/
每个测试方法都会对传入参数进行比较,并返回 true 或 false。这些方法还会把信息打印出来,以表示自己正在被调用。这些测试方法被用在了下面的表达式中:testl(0) && test2(2) && test3(2)
你可能会很自然地认为这三个测试都会执行,但输出显示并不是这样的。第一个测试生成的结果是true,所以表达式继续执行。但第二个测试生成了 false。这就意味着整个表达式肯定为 false,所以剩余的表达式就没必要继续执行了,它可能会很耗费资源。事实上,之所以存在短路,就是因为如果逻辑表达式有一部分不必计算,那我们就能获得潜在的性能提升。