2012-11-16 40 views
4

可能重複:
Difference in & and &&Java的邏輯「與」 VS「或」短路一致性

我讀過一些教程,並回答關於java和我短路操作我仍然不完全理解java處理雙垂直管道短路的方式與雙和號的區別。例如...

爲什麼邏輯與短路評估失敗?

引用JSL 15.23。有條件與操作員& &

The conditional-and operator && is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.

public static void main(String... args) { 


    int a = 1; 

    int b = 2; 

    // Okay. Prints 
    if(a == 1 | b == 3) { 

     System.out.println("Comparison via |" + "\na is " + a + "\nb is " + b); 

    } 

    // Okay. Prints 
    if(a == 1 || b == 3) { 

     System.out.println("Comparison via ||" + "\na is " + a + "\nb is " + b); 

    } 

    // Okay. Does not print 
    if(a == 1 & b == 3) { 

     System.out.println("Comparison via &" + "\na is " + a + "\nb is " + b); 

    } 

    // I don't understand. Shouldn't the Short Circuit succeed since the left side of the equation equals 1? 
    if(a == 1 && b == 3) { 

     System.out.println("Comparison via &&" + "\na is " + a + "\nb is " + b); 

    } 

} 
+3

'|'和'&'是按位或/和運算符;它們不同於'||'和'&&',它們是邏輯或/和運算符。 – NullUserException

+0

我知道我沒有得到第四名,但是......我迷失在那裏:-) –

+0

@NullUserException:他們在短路方面有所不同 - 但JLS在另一方面定義了一個。 ..看到我的答案。 (注意對於'boolean'操作數,它們仍然是邏輯運算符...) –

回答

10

我不明白。由於等式的左邊等於1,短路是否應該成功?

不,絕對不是。 &&這一點就是結果只有true如果左邊的右邊的操作數是true;短路意味着如果左操作數是false,則右操作數不會被評估,因爲答案在該點是已知的。

你應該閱讀部分15.23和JLS的15.24瞭解更多詳情:

的條件和操作& &就像&(§15.22.2),但評估其右邊的操作數只有當其左手操作數的值爲true。

條件或運算符||運算符就像| (§15.22.2),但只有在其左側操作數的值爲假時才評估其右側操作數。

+0

謝謝......明白了......有區別...我必須練習這使它成爲'具體':-) –

1

邏輯運算符||&&短路如果結果是評估第一操作數後確定。對於||,如果第一個操作數的計算結果爲true,則爲&&,如果計算結果爲false

如果||第一操作數是false,它仍然可以產生的true的整體結果,如果第二操作數是true。同樣,如果&&的第一個操作數是true,如果第二個操作數是false,它仍然可以計算爲false

在Java中,運營商和|&不僅位運算符(當應用於整數參數),也不管第一值的計算結果兩個操作數的非短路邏輯運算符。

0
if(a == 1 && b == 3) { 
    System.out.println("Comparison via &&" + "\na is " + a + "\nb is " + b); 
} 

首先,它檢查,如果a == 1這是真的,所以它去,並檢查b == 3,這是不正確的,所以true && falsefalse和你沒有得到輸出。

,如果你有

if(b == 3 && a == 1) { 
     System.out.println("Comparison via &&" + "\na is " + a + "\nb is " + b); 
} 

那就先檢查是否b == 3因爲做法並不甚至懶得在a == 1尋找,因爲false && whatever總是false,不管什麼whatever就是如此。

這是否回答你的問題?

1

&和& &要求雙方都是正確的,所以代碼的行爲如預期。

唯一的區別是,&執行雙方,但& &僅執行第一如果是假的,因爲右邊的會是風馬牛不相及的最終結果。

這樣做的效果是對於像

if (obj == null || obj.isSomthing()) 

代碼很重要,如果你使用會拋出一個NPE | obj爲null。

+0

這是一條滑溜的魚...... ;-) –

+0

將變量換成布爾值後變得很清晰:-) –

2

當與boolean被使用過,按位運算符(|&)是除了類似到邏輯運算符(||&&):

  • &&的情況下,如果第一個參數是false第二個是未評估的,因爲整個表達式必須是false。對於&,兩個參數都進行評估。

  • ||的情況下,如果第一個參數是true第二留下未計算的,這是因爲整個表達隨後必須true。對於|,兩個參數都進行評估。

這就是我們所說的「短路」:剛剛從第一個參數的值,離開第二個參數未計算的,因爲在某些情況下,我們可以知道整個表達式的值的過程。


現在你問爲什麼下面的表達式是falsea == 1 && b == 3。那麼短路與它無關; a = 1b = 2,所以聲明"a is 1 and b is 2顯然是false,因爲b不是2

+0

** tl; dr **:按位('|'和'&')運算符評估兩個參數,無論如何;邏輯運算符('||'和'&&')*可以*(但不總是)短路。 – NullUserException

+0

@NullUserException他們什麼時候不短路? – arshajii

+0

在OP的例子中,它沒有短路。 – NullUserException