你真的瞭解Java中的位操做?

位操做謎題

下面這行代碼會輸出什麼?html

byte b = -1;
System.out.println(b & 0xff);

一個byte佔8位,再和8位都爲1的0xff與操做,那麼結果應該是它自己纔對,但是運行上面的代碼輸出倒是255。 要想讀懂上面的代碼,首先咱們要弄清楚如下幾個問題。java

Java如何編碼正數和負數?

在Java中數值類型的首位(bit)表示符號位,0表示正數,1表示負數。可是須要注意的是,因爲Java採用」2的補碼「(Two's Complement)編碼負數,因此若是把負數的首位改爲0,修改後的值和其絕對值並不相等,因此處理負數時要格外當心。數組

位操做符(Bitwise Operators)的操做數類型是什麼?

Java語言規範[2]中明確指出位操做符(Bitwise Operators)只做用於integer類型(其實也能夠做用於long類型)。因此若是操做數是byte/short類型,則在位操做以前會被轉換成integer類型。詳情請參考Java 語言規範 5.6.2. Binary Numeric Promotionoracle

0xff返回的類型是什麼?

0xff返回的是32位integer類型。在Java中integer類型(例如1)有三種表示方式:十進制(1)、八進制(01)和十六進制(0x01)。編碼

byte類型如何被轉換成integer類型?

在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.");
        }
    }
}

參考

相關文章
相關標籤/搜索