通过字节码来分析Java位移操作

字节位移

位移是在一个字节二进制(只能是0和1)的基础上进行位的移动操作,一个字节有8位组成,理论上位移后空出的位由0不足。比如11111111,往左移1位(<<1)就应该是11111110,往右移一位(>>1)为011111111.

实践

都是在以下字节的前提下进行操作

byte[] b = new byte[2];
b[0] = (byte) 0xff;//255
System.out.println(Integer.parseInt(Integer.toBinaryString(b[0]&0xff), 2));
System.out.println(b[0]);//java 中有符号的-1
System.out.println(Integer.toBinaryString(b[0]&0xff));//输出二进制字符串,按位与只输出8位一个字节

输出

255
-1
11111111
左移2位,期望11111100;
b[0] = (byte) (b[0] << 2);
System.out.println(Integer.parseInt(Integer.toBinaryString(b[0]&0xff), 2));
System.out.println(b[0]);//java 中有符号的-4
System.out.println(Integer.toBinaryString(b[0]&0xff));//输出二进制字符串,按位与只输出8位一个字节

结果

252
-4
11111100

可以看到与我们期望的结果一致

右移2位期望得到00111111
b[0] = (byte) (b[0] >> 2);
System.out.println(Integer.parseInt(Integer.toBinaryString(b[0]&0xff), 2));
System.out.println(b[0]);
System.out.println(Integer.toBinaryString(b[0]&0xff));//输出二进制字符串,按位与只输出8位一个字节

结果

255
-1
11111111

可以看到,并不是我们原先期望的结果,不是由0填充的,而是由1填充的,这是为什么呢?
Java中byte有4位,范围从-128到127,即从11111111到01111111,二进制中最高的一个位只是标志位,并不进行运算,0代表正数,1代表负数。在进行位移时,byte先转成int类型,我们知道,int由32个位组成,在byte转成int 中,不足的位如果是正数则有0填充,负数则有1填充。所以-1其实是在位移时是都是由1对空出的位进行填补,左移不受影响,右移正数不受影响。

正确的操作

取低8位进行位移

b[0] = (byte) ((b[0]&0xff) >> 2);

从字节码来看byte的位移

在这里插入图片描述

		57: aload_1
        58: iconst_0
        59: aload_1 //从局部变量1中装载引用类型值入栈。
        60: iconst_0 //0(int)值入栈。
        61: baload //从boolean类型数组或byte类型数组中装载指定项的值(先转换为int类型值,后压栈)。
        62: sipush        255 //(valuebyte1 << 8) | valuebyte2 值带符号扩展成int值入栈。
        65: iand //对int类型按位与运算。
        66: iconst_2 //2(int)值入栈。
        67: ishr //算术右移int类型值。
        68: i2b //将栈顶int类型值截断成byte类型,后带符号扩展成int类型值入栈。
        69: bastore
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里藍天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值