下面這行代碼會輸出什麼?html
byte b = -1; System.out.println(b & 0xff);
一個byte佔8位,再和8位都爲1的0xff與操做,那麼結果應該是它自己纔對,但是運行上面的代碼輸出倒是255。 要想讀懂上面的代碼,首先咱們要弄清楚如下幾個問題。java
在Java中數值類型的首位(bit)表示符號位,0表示正數,1表示負數。可是須要注意的是,因爲Java採用」2的補碼「(Two's Complement)編碼負數,因此若是把負數的首位改爲0,修改後的值和其絕對值並不相等,因此處理負數時要格外當心。數組
Java語言規範[2]中明確指出位操做符(Bitwise Operators)只做用於integer類型(其實也能夠做用於long類型)。因此若是操做數是byte/short類型,則在位操做以前會被轉換成integer類型。詳情請參考Java 語言規範 5.6.2. Binary Numeric Promotion。oracle
0xff返回的是32位integer類型。在Java中integer類型(例如1)有三種表示方式:十進制(1)、八進制(01)和十六進制(0x01)。編碼
在Java中窄類型向寬類型轉換時須要進行符號位擴展,若是該byte是負數則左邊要補齊相應個數1,若是是正數則要補齊相應個數0..net
咱們再回頭看上面的代碼:code
b & 0xff
在&操做以前,b被轉換成integer類型,左邊用符號位1補齊:htm
11111111 11111111 11111111 11111111
0xff是integer字面量,二進制值爲:blog
00000000 00000000 00000000 11111111
執行&操做,結果爲:get
00000000 00000000 00000000 11111111
返回結果是integer類型,符號位是0,因此是一個正數,值爲255。
下面是一個更復雜的例子,功能是將長度爲4的byte數組轉換成integer類型:
public class BytesArrayToInt { public static void main(String[] args) { System.out.println(byteArrayToInt(new byte[]{0x01, 0x01, 0x01, 0x01})); } public static int byteArrayToInt(byte[] b) { if (b.length == 4) { return b[0] << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff); } else { throw new InvalidParameterException("The bytes array length must be 4."); } } }