先來看個栗子:
|
bs是由一段字符串經過MD5加密後輸出的byte數組。在for循環裏,bs[i]是一個8位二進制,而0xFF的二進制爲11111111,那麼bs[i]與0xFF進行與運算,得到仍爲bs[i],不是多此一舉嗎,爲什麼要這樣做呢?
在搞清楚之前,需要理解計算機存儲機制以及原碼、反碼、補碼的概念:
在學計算機原理時,知道計算機內部的存儲都是利用二進制的補碼進行存儲的,如果用1個字節表示一個數字,一個字節有8位,超過8位就進1,在內存中的情況爲:100000000,進位1被丟掉。
來回顧下反碼、補碼的概念:
反碼
對於正數,反碼和原碼相同;
對於負數:反碼是除符號位1之外的都取反。
補碼:就是對反碼加1
比如:
-1 的原碼:10000001
-1 的反碼:11111110
+1
-1 的補碼:11111111
0 的原碼:00000000
0 的反碼:11111111(正零和負零的反碼相同)
+1
0 的補碼:100000000 (1丟掉,正零和負零的補碼相同)
-----------------------------------------------------------------------------------
由上述可知,byte a = -127(原碼:11111111)在內存中會以其補碼(10000001)的形式存儲,在做byte -> int類型轉換時,JVM會做一個補位處理,由於int類型爲32位,所以補位後的補碼爲:11111111 11111111 11111111 10000001(32位),這個32位二進制補碼也是-127。(注:補位是補1還是補0,取決於byte的最高位是1還是0)
我們發現,在byte -> int轉換時,計算機存儲的補碼和JVM補位後的補碼錶示的十進制數字仍然是相同的。
所以,在byte類型轉爲int類型時,爲什麼要和0xFF(原碼:11111111)做與運算?其本質原因是要和二進制補碼保持一致。當byte轉int時,高24位必然會補1,這時與其二進制補碼已經不一樣了,補位後的補碼與0xFF 做與運算,可以將高24位置爲0,低8位保持不變,這樣做就可以保證和二進制補碼的一致了。