Java開發筆記(十五)短路邏輯運算的優點

前面提到邏輯運算只能操做布爾變量,這實際上是不嚴謹的,由於通過Java編程實現,會發現「&」、「|」、「^」這幾個邏輯符號居然能夠對數字進行運算。譬以下面的代碼就直接對數字分別開展了「與」、「或」、「異或」運算:java

		// 3的二進制爲00000011,7的二進制爲00000111
		int andNumber = 3&7; // 對兩個數字進行「按位與」運算
		System.out.println("andNumber="+andNumber);
		int orNumber = 3|7; // 對兩個數字進行「按位或」運算
		System.out.println("orNumber="+orNumber);
		int xorNumber = 3^7; // 對兩個數字進行「按位異或」運算
		System.out.println("xorNumber="+xorNumber);

 

上述代碼也能成功編譯運行,運行結果以下所示:編程

andNumber=3
orNumber=7
xorNumber=4

 

究其緣由,這三個邏輯符號原是按位邏輯運算。所謂按位邏輯,指的是先將操做數轉成二進制,再對二進制的操做數逐位進行邏輯運算,最後把每位的邏輯結果從新拼成一個二進制的運算值。例如數字3的二進制表達爲00000011,數字7的二進制表達爲00000111,那麼對這兩個二進制數進行「按位與」運算,獲得的二進制結果爲00000011即數字3;一樣對這兩個二進制數進行「按位或」運算,獲得的二進制結果爲00000111即數字7;繼續對這兩個二進制數進行「按位異或」運算,獲得的二進制結果爲00000100即數字4。
以上的實驗結果,說明了邏輯與、或、異或符號實質是按位邏輯運算,以前的布爾變量只是按位邏輯的一種運算類型。既然按位邏輯比較的是左右兩邊的各個二進制位,就意味着必須先肯定左右兩邊的操做數值,而後才能對兩個操做數進行按位運算。這麼看來,按位邏輯並不是真正意義上的邏輯操做,正常狀況的邏輯運算應當具有下列特徵:
一、只判斷真和假,不判斷0和1,更不是什麼逐位判斷;
二、對於「與」運算,一旦左邊的操做數爲假,則無論右邊爲什麼,運算結果必定爲假;
三、對於「或」運算,一旦左邊的操做數爲真,則無論右邊爲什麼,運算結果必定爲真;
對比發現,按位邏輯不但不符合上述的第一點特徵,也不符合第二點和第三點特徵,由於按位邏輯須要左右兩邊都肯定以後,才能墨守成規進行邏輯運算。顯然這樣作並不經濟,假若左邊操做數就能肯定運算結果,那又何苦多此一舉進行右邊的冗餘計算?爲解決按位邏輯存在的問題,Java引入了新的短路符號來幫忙,包括短路與符號「&&」和短路或符號「||」,短路的意思是:若是左邊已經接通,那就不繞道右邊了。
話雖如此,但又如何證實短路邏輯是否真的高效呢?下面經過一個例子來分辨按位邏輯和短路邏輯之間的區別,關鍵在於邏輯符號的右邊須要修改變量值,爲此引入了自增符號「++」。具體的邏輯運算代碼以下所示,主要是比較邏輯與「&」和短路與「&&」的運算結果:日誌

		int i=1, j=1;
		// 對於按位邏輯運算,須要等待左右兩邊都計算完畢,而後進行按位邏輯判斷
		boolean result1 = 3>4 & ++i<5;
		System.out.println("result1="+result1);
		System.out.println("i="+i);
		// 對於短路邏輯運算,一旦左邊的計算可以肯定結果,就當即返回邏輯判斷的值,此時再也不進行右邊的計算
		boolean result2 = 3>4 && ++j<5;
		System.out.println("result2="+result2);
		System.out.println("j="+j);

 

運行以上示例代碼,獲得下述的運算日誌:blog

result1=false
i=2
result2=false
j=1

 

可見兩個邏輯式子的運算結果都爲false,不一樣之處在於:「&」符號同時進行了左右兩邊的運算,因此i++執行以後i值變爲2;而「&&」符號先進行左邊運算,發現3>4爲假,說明與運算確定爲假,此時整個式子直接返回假,再也不執行右邊的計算,因而j值仍然爲1(j++未執行)。從該實驗看到,短路邏輯運算名副其實,其效率高於按位邏輯運算,於是在實際開發過程當中,更常用短路符號「&&」和「||」進行邏輯運算,不多使用單個的「&」和「|」。開發

相關文章
相關標籤/搜索