java 0XFF在byte转int中的作用

0XFF 为16进制数,用二进制表示为 1111_1111。
有时看到将byte转为int时会这样转:
bytes是一个byte数组,将bytes中的内容转成int。

int a = bytes[i]&0xFF;

为什么要这样转呢?
直接:
int a =bytes[i];
不行吗?
看以下代码:

 static void HexOxFF(){
       byte a= (byte) 0xfd;
       int b = a;
       Integer c = a&0xff;
       System.out.println(a);
       System.out.println(b);
       System.out.println(c);
}

输出结果为:
-3
-3
253

0xfd 的二进制为:1111 1101
如果直接将二进制转为十进制的话应该是:

2^0+2^2+2^3+2^4+2^5+2^6+2^7=253

为啥直接输出和直接转成int变成-3了?
接下来就是重点了
在计算机中所有东西都是用0和1表示的,我们直接将上面的程序变成下面:

 static void HexOxFF(){
        byte a= (byte) 0b1111_1101;
        int b = a;
        Integer c = a&0b1111_1111;
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }

注意:0b开头表示为二进制数。
结果和之前是一样的。
这里说一个知识点:

正数的源码,反码,补码都是一样的。例如
3的源码:0000_0011
反码:0000_0011
补码:0000_0011
负数的补码是反码加一。例如
-3的原码:1000_0011
反码:1111_1100
补码:1111_1101
(这三个码不熟悉的请百度)
并且二进制在计算机中都是以补码的形式出现的。

因此程序中的0xfd 即0b1111_1101是一个补码,不能直接转为10进制,需要变成原码才能转化,转换后的原码为:1111_1101->1111_1100->1000_0011
最终原码为:1000_0011。
所以为-3。
(注意:byte最高位为符号位 0表示正数,1表示负数)
这样看byte 直接转int 数值是没有发生改变的,为啥还要进行&0xFF操作呢?

注意了在java 中 byte是有符号的最高位是符号位转10进制的时候不能对它进行转换。而在现实中我们经常在socket中获取byte数组,并且其中的byte是无符号的,最高位是要进行转化的,直接转就变成有符号的了,数值就不对了。

在这种情况下,byte 转int我们需要的是将8个bit都转成话而不是7个bit。
那&0xFF是怎么实现这个要求的呢?

我们知道int 占32个bit 而byte占8个bit。在byte转int的时候就要填充空缺的位置变成32个bit。这个填充的时候是怎么填充的呢?转换的时候填充byte的符号位。例如:
1、一个byte为 0b0000_0011。
转为int 填充到32位,符号位为0,填充结果为:
0b0000_0000_0000_0000_0000_0000_0000_0011
2、一个byte为 0b1000_0011。
转为int 填充到32位,符号位为0,填充结果为:
0b1111_1111_1111_1111_1111_1111_1000_0011

可以通过java程序验证:

 		byte a= (byte) 0b0000_0011;
        int b = 0b0000_0000_0000_0000_0000_0000_0000_0011;
        int b2 = a;
        System.out.println(a);
        System.out.println(b);
        System.out.println(b2);

        byte c= (byte) 0b1000_0011;
        int d = 0b1111_1111_1111_1111_1111_1111_1000_0011;
        int d2=c;
        System.out.println(c);
        System.out.println(d);
        System.out.println(d2);

结果:
3
3
3
-125
-125
-125

而对byte 进行&0xFF运算就是将转为int时补充的数字同意变成0,这样保证符号位为0即为正数,而正数的补码,反码,原码时一样的,从而实现了byte无符号转int。

注意:在bytes[i]&0xff时,bytes[i]已经变成了int,因为0xff时一个int,进行&运算两个数必须有同样的位数,java会自动将byte[i]转换成int。所以实际位下面这个式子:
例如:bytes[i]=0b1000_0011
那么bytes[i]&0xff 等效于下面这个:
0b1111_1111_1111_1111_1111_1111_1000_0011
&
0b0000_0000_0000_0000_0000_0000_1111_1111
=
0b0000_0000_0000_0000_0000_0000_1000_0011

这还有一个要注意的:
0xff不是一个byte而是int,如果程序直接写byte a = 0xff;是会报错的。
0xff 在java 里面补全就是0x000000ff,因此二进制就是:
0b0000_0000_0000_0000_0000_0000_1111_1111

这样写 byte a = (byte)0xff才不会报错,此时二进制表示位0b1111_11111;
如果再将a直接转成int的话就不是原来那个0xff咯。看到这里如果你懵逼的话请自己从新边看文章边敲代码试一下哦。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值