2016-03-08 82 views
7

實際的Java代碼:爲什麼java的恢復邏輯運算符,而編譯

((rrd == null || !rrd) 
    && null != dam 
    && null != dam.getac() 
    && null != dam.getac().getc() 
    && null != sname 
    && sname.equalsIgnoreCase(dam.getac().getc())) 

但是,當我看着類文件是:

((rrd != null) && (rrd.booleanValue())) 
    || ((((null == dam) 
    || (null == dam.getac()) 
    || (null == dam.getac().getc()) 
    || (null == sname) 
    || (!(sname.equalsIgnoreCase(dam.getac().getc())))))) 

所有||&&互換。

任何人都可以解釋爲什麼嗎?

+2

請問下面的問題:1)至少近似類型的rrd,dam,sname; 2)javap輸出,而不是你的反向工程版本。謝謝。 – Koshinae

+1

由於OR操作可能會短路。第一個或者是真的使得整個邏輯運算成立。此外,你應該從不**寫出這樣令人費解的邏輯陳述。他們對於人類理解太複雜。 –

+0

嗨Koshinae,'rrd','dam'和'sname'類型分別是'Boolean','java entity'和'String'。 –

回答

-1

參見:De Morgans Laws

一個|| !B ==!(A & & B)

+4

我認爲OP知道'!A || !B ==!(A && B)'。但問題是**爲什麼**編譯器將其更改爲此。 –

+1

正常情況下,編譯器會這樣做,以優化性能,因爲某些操作可以比其他操作更快地執行。 – Christian

+0

我不希望這是一個優化 - 我希望它是OP所使用的反編譯器無法區分差異,或者它編譯成完全相同的字節碼。 –

2

這些表達式並不等同,但相反。它看起來像編譯器避免了一個外部(或暗示)不在這裏。

注意,短路可能是兩種操作,||&& - 在第一種情況下,當遇到真正的子表達式和在第二種情況下,當遇到一個假子表達式。所以單獨短路的能力並不能解釋這一點。