2012-03-30 151 views
7

在下面的代碼片段考慮與評論等同安定使用0xff,澄清需要

1. private static String ipToText(byte[] ip) { 
2. StringBuffer result = new StringBuffer(); 
3. 
4. for (int i = 0; i < ip.length; i++) { 
5.  if (i > 0) 
6.   result.append("."); 
7. 
8.  result.append(ip[i]); // compare with result.append(0xff & ip[i]); 
9. } 
10. 
11.  return result.toString(); 
12. } 

.equals()測試替換第8行確認加入0xff不會改變任何東西。是否有這個面具適用的原因?

+0

我不確定,但看起來像轉換爲無符號字節。 – Osw 2012-03-30 20:23:58

回答

16

byte在Java中是−之間的數字128和127(無符號數,就像Java中的每個整數(除了char如果要計數))。通過與0xff安定你強迫它是一個積極的int 0和255之間

它的工作原理,因爲Java將執行擴大轉換到int,使用符號擴展,所以不是一個消極byte你將有一個負int。用0xff屏蔽將只留下較低的8位,從而使數字再次爲正數(以及您最初的想法)。

你可能因爲你只用byte[]測試沒有注意到的差值小於128

小例子:

public class A { 
    public static void main(String[] args) { 
     int[] ip = new int[] {192, 168, 101, 23}; 
     byte[] ipb = new byte[4]; 
     for (int i =0; i < 4; i++) { 
      ipb[i] = (byte)ip[i]; 
     } 

     for (int i =0; i < 4; i++) { 
      System.out.println("Byte: " + ipb[i] + ", And: " + (0xff & ipb[i])); 
     } 
    } 
} 

這將打印

Byte: -64, And: 192 
Byte: -88, And: 168 
Byte: 101, And: 101 
Byte: 23, And: 23 

顯示byte中的內容與當它仍然是int時的字節之間的差異以及什麼e運行的結果是&

+0

回覆:「這是因爲0xff'是int類型的,因此該字節也被提升爲'int'」:即使兩個參數的類型都是'byte',實際上也會發生類型提升爲'int' ; Java對'byte'沒有明確的'&'操作符。 (並且在沒有'&'的版本中,在重載解析期間將類型提升爲'int',因爲'StringBuffer'沒有'append(byte)'方法。) – ruakh 2012-03-30 20:24:48

+0

事實上,你是對的。相關的部分很明顯,無論如何我們都得到了一個符號擴展爲'int'的方法,通過屏蔽低8位,我們可以強制它成爲一個無符號的字節:) – Joey 2012-03-30 20:26:41

1

在這個例子中,我不明白它會有什麼不同。您正在使用一個字節0xff。根據定義,一個字節有8位,並且添加屏蔽掉最後的8位。所以你拿走了8的8分,這是不會做任何事情的。

如果你和它一起使用的東西比一個字節,一個短的或一個整數或者其他什麼都要大,那麼使用0xff就會有意義。

+0

或只是大於127;) – Joey 2012-03-30 20:24:57

+0

哎呀,我承認,我誤解了這個問題。我正在考慮將它放回到一個字節數組中,我沒有注意到它將它轉換爲文本。 – Jay 2012-04-26 18:56:34

1

這應該只會有負面的字節時有所作爲。 & 0xff通常用於將字節解釋爲無符號。

3

由於您已經在這裏處理了一個字節數組,並且您正在執行按位操作,所以您可以忽略Java如何將所有字節視爲已簽名。畢竟,你現在正在進行比特級別的比特級別的比特級別的「簽名」或「無符號」值。

掩蓋一個8位值(一個字節)的全1,只是浪費週期,因爲沒有東西會被屏蔽。如果兩個比較結果都爲真,則bitewise AND會返回真,因此如果掩碼包含全1,那麼可以保證在AND操作之後掩碼值的所有位都保持不變。

請看下面的例子:

Mask off the upper nibble: 
    0110 1010 
AND 0000 1111 (0x0F) 
    = 0000 1010
Mask off the lower nibble: 
    0110 1010 
AND 1111 0000 (0xF0) 
    = 0110 0000
Mask off... Eh, nothing: 
    0110 1010 
AND 1111 1111 (0xFF) 
    = 0110 1010 

當然,如果你用一個完全成熟的INT在這裏工作,你會得到別人是結果說:你」 d「強制」int爲無符號字節的等價物。