2012-03-30 148 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为无符号字节的等价物。