我們經常會看到這樣的語法
(byte) 0xAD
0xAD實際是個16進制,轉換成二進制為:10101101,轉換成10進制是:173,它是個正數
10101101只是int的簡寫,int由4個byte字節,即32位bit組成,實際的值是
(00000000 00000000 00000000 )10101101
int由4 byte組成,因此int轉byte是會掉位的,直接截取最后一個字節,即:
10101101
符號位是1,因此它是負數,負數的存儲方式是補碼。因此要先求出補碼才能計算值。
求補碼方式為:
符號位不變,其他位取反,然后+1,映射到這里則為
11010010 + 1 -> 11010011 則值為 -(2^6+2^4+2^1+2^0) = -83
因此0xAD = 173 ,(byte) 0xAD=-83
有時候,我們會有一種特殊的需求,比如用bit位上的0或者1表明某一個值是否存在,如
0000 0101 可以表示第0位 -> 1 -> 存在
第1位 -> 0 -> 不存在
第2位 -> 1 -> 存在
……
這樣,一個byte就能表示8個位置是否有值,可用於8個不同類型的值是否存在,或者用於排序數字
這樣做的好處是利用一個byte有8bit的特點標識8種情況,大量節省了空間,並且當一個byte轉換成二進制時,可以立即清楚某一位是否存在,從這個意義上來說,他比你聲明8個byte更清晰,而且標識的范圍更廣,因為他還可以處理同時存在的邏輯。
當然,有利就有弊,如果想用於數據庫按標識查詢,則需要人為來處理多種情況,這甚至是及其復雜的,諸如存在mysql某一列,又需要按字段進行條件匹配時,不推薦此方式
當獲取到byte,判斷某一位bit是否為1的方式
/** * 比如3的二進制是 0000 0011 * isBitV1(3,0) 是1 true * isBitV1(3,1) 是1 true * isBitV1(3,2) 是0 false * 判斷byte的某一位上是否有值 * * 0x1其實就是1,1的二進制是0000 0001 * @param b * @param position 第幾位 * @return */ private boolean isBitV1(byte b, int position) { if (position == 0) { return (b & 0x1) > 0; } else { return (b >> position & 0x1) > 0; } }
0x1是16進制,表示1,之所以很多源碼里面喜歡用0x1,而不是1,我推測是這樣少了一次int轉2進制或16進制的轉換,效率更高
