邏輯運算符AND(&&)、OR(||)以及NOT(!)能生成一個布爾值(true或false)——以自變量的邏輯關系為基礎。下面這個例子向大家展示了如何使用關系和邏輯運算符。
//: Bool.java
// Relational and logical operators
import java.util.*;
public class Bool {
public static void main(String[] args) {
Random rand = new Random();
int i = rand.nextInt() % 100;
int j = rand.nextInt() % 100;
prt("i = " + i);
prt("j = " + j);
prt("i > j is " + (i > j));
prt("i < j is " + (i < j));
prt("i >= j is " + (i >= j));
prt("i <= j is " + (i <= j));
prt("i == j is " + (i == j));
prt("i != j is " + (i != j));
// Treating an int as a boolean is
// not legal Java
//! prt("i && j is " + (i && j));
//! prt("i || j is " + (i || j));
//! prt("!i is " + !i);
prt("(i < 10) && (j < 10) is "
+ ((i < 10) && (j < 10)) );
prt("(i < 10) || (j < 10) is "
+ ((i < 10) || (j < 10)) );
}
static void prt(String s) {
System.out.println(s);
}
} ///:~
只可將AND,OR或NOT應用於布爾值。與在C及C++中不同,不可將一個非布爾值當作布爾值在邏輯表達式中使用。若這樣做,就會發現嘗試失敗,並用一個“//!”標出。然而,後續的表達式利用關系比較生成布爾值,然後對結果進行邏輯運算。
輸出列表看起來象下面這個樣子:
i = 85 j = 4 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 true
注意若在預計為String值的地方使用,布爾值會自動轉換成適當的文本形式。
在上述程序中,可將對int的定義替換成除boolean以外的其他任何主數據類型。但要注意,對浮點數字的比較是非常嚴格的。即使一個數字僅在小數部分與另一個數字存在極微小的差異,仍然認為它們是“不相等”的。即使一個數字只比零大一點點(例如2不停地開平方根),它仍然屬於“非零”值。
1. 短路
操作邏輯運算符時,我們會遇到一種名為“短路”的情況。這意味著只有明確得出整個表達式真或假的結論,才會對表達式進行邏輯求值。因此,一個邏輯表達式的所有部分都有可能不進行求值:
//: ShortCircuit.java
// Demonstrates short-circuiting behavior
// with logical operators.
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) {
if(test1(0) && test2(2) && test3(2))
System.out.println("expression is true");
else
System.out.println("expression is false");
}
} ///:~
每次測試都會比較自變量,並返回真或假。它不會顯示與准備調用什麼有關的資料。測試在下面這個表達式中進行:
if(test1(0)) && test2(2) && test3(2))
很自然地,你也許認為所有這三個測試都會得以執行。但希望輸出結果不至於使你大吃一驚:
if(test1(0) && test2(2) && test3(2))
第一個測試生成一個true結果,所以表達式求值會繼續下去。然而,第二個測試產生了一個false結果。由於這意味著整個表達式肯定為false,所以為什麼還要繼續剩余的表達式呢?這樣做只會徒勞無益。事實上,“短路”一詞的由來正種因於此。如果一個邏輯表達式的所有部分都不必執行下去,那麼潛在的性能提升將是相當可觀的。