邏輯運算符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,所以為什麼還要繼續剩余的表達式呢?這樣做只會徒勞無益。事實上,“短路”一詞的由來正種因於此。如果一個邏輯表達式的所有部分都不必執行下去,那麼潛在的性能提升將是相當可觀的。