《轉》 Java中byte型別變數做& 0xff運算的理解
=Java中byte型別變數做& 0xff運算的理解
在IO字元操作或加密計算時經常會見到byte值與0xff做與運算,這種寫法首次看到會有些不解,其實也比較容易理解。
下面說下我個人的理解
首先要明白,字元編碼中沒有負值表示一個字元的,至少我沒有遇到過,可以看下ascii編碼,全部都是使用正值表示字元的,例如65
表示A。
其次要明白byte & 0xff 的位運算的意義
在Java中byte型別變數的表示範圍是: -128 ~ 127 ,是帶符號的,即最高位的1表示負數,0表示正數。byte變數與0xff執行&運算後,就將byte的低8位數值截取出來了,其實byte二進位制本來就8位,由於Java中預設是按照int來處理(記得大學時學習有這麼一說,沒嚴格確認過),這樣運算後的效果簡單說就是將符號位當作一般數字位來看待了。
例如 -124用二進位制表示就是”10000100”,如果將最高位的1看作一般數字位,那麼數值就是132,這與int型別數值為132的二進位制表示的低8位是一致的。
為什麼要執行byte & 0xff?
其實如果byte型別數字轉int,long等型別,是不需要這樣操作的,Java中會自動轉換,做這種操作的情況,我認為有兩種情況:
- 有符號數當作無符號數來看待;
- 要用十六進位制表示的地方,如計算好雜湊值後,將byte陣列轉換為十六進位制的字串。
為什麼Java中用十六進位制的地方可能會有byte & 0xff形式的運算呢?
我認為Java中沒有直接將二進位制字串表示為十六進位制字串的方法,導致大家要利用Integer.toHexString()這個方法來實現轉換,很顯然這個方法是Int變數才能用的,所以需要先轉換為無符號的數值向上自動轉型的int型別,即進行byte & 0xff運算。
下面的程式碼是將一個byte陣列轉為十六進位制的字串,提示一下如果byte的二進位制表示的高4位是”0000”,就用”0”來填充,從數值上來說就是大於0小於16。
/**
* 將byte陣列轉為十六進位制字串
* @param byteArray
* @return
*/
public static String byteArrayToHexStr(byte[] byteArray){
StringBuilder sb = new StringBuilder();
for(byte b : byteArray){
if(b >= 0 && b < 16 ){
sb.append('0');
}
sb.append(Integer.toHexString(b & 0xff));
}
return sb.toString();
}