IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

java中byte转换int时为何与0xff进行与运算

本机暂存

   先看代码:

public static String bytes2HexString(byte[] b) {
 String ret = "";
 for (int i = 0; i < b.length; i++) {
 String hex = Integer.toHexString(b[ i ] & 0xFF);
 if (hex.length() == 1) {
 hex = '0' + hex;
 }
 ret += hex.toUpperCase();
 }
 return ret;
}

   上面是将byte[]转化十六进制的字符串,注意这里b[ i ] & 0xFF将一个byte和 0xFF进行了与运算,然后使用Integer.toHexString取得了十六进制字符串,可以看出:b[ i ] & 0xFF 运算后得出的仍然是个int,那么为何要和 0xFF 进行与运算呢?直接 Integer.toHexString(b[ i ]);,将 byte 强转为 int 不行吗?答案是不行的。

   其原因在于:

   1.byte的大小为 8bits 而 int 的大小为 32bits ;

   2.java的二进制采用的是补码形式 ;

   在这里先温习下计算机基础理论:

   byte是一个字节保存的,有8个位,即8个0、1。

   8位的第一个位是符号位,也就是说0000 0001代表的是数字1 ,1000 0001代表的就是-1 。

   所以正数最大位0111 1111,也就是数字127;负数最大为1111 1111,也就是数字-128 。

   上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码(补码就是原码按位取反再加1,下边的解释有些抽象。):

   1、反码:

   一个数如果是正,则它的反码与原码相同;

   一个数如果是负,则符号位为1,其余各位是对原码取反;

   2、补码:利用溢出,我们可以将减法变成加法

   对于十进制数,从9得到5可用减法:

   9-4=5 因为4+6=10,我们可以将6作为4的补数

   改写为加法:

   9+6=15(去掉高位1,也就是减10)得到5.

   对于十六进制数,从c到5可用减法:

   c-7=5 因为7+9=16 将9作为7的补数

   改写为加法:

   c+9=15(去掉高位1,也就是减16)得到5.

   在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

   ⑴一个数为正,则它的原码、反码、补码相同

   ⑵一个数为负,则符号位为1,其余各位是对原码取反,然后整个数加1

   - 1的原码为 10000001

   - 1的反码为 11111110

    + 1

   - 1的补码为 11111111

   0的原码为 00000000

   0的反码为 11111111(正零和负零的反码相同)

    +1

   0的补码为 100000000(舍掉打头的1,正零和负零的补码相同)

   Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,例如补码11111111的十进制数为 -1 ,转换为int时变为 11111111111111111111111111111111,好多1啊,呵呵!即 0xffffffff,但是这个数是不对的,这种补位就会造成误差。

   和0xff相与后,高24比特就会被清0了,结果就对了。

   重要信息:

   Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

   而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。

同分类推荐文章

  1. Go 实验特性详解 (2026-06-21 10:05:27)
  2. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)
  3. Loop Engineering 实践:我把 RDMA 开发库移植到 Go 语言,花费 239 块钱 (2026-06-17 04:00:24)

查看更多 后端 文章 →

建议继续学习

  1. SmartSprites - 命令行形式的CSS Sprites生成器 (累计阅读 123,867)
  2. Java开发岗位面试题归类汇总 (累计阅读 22,115)
  3. android 开发入门 (累计阅读 19,495)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,118)
  5. HashMap解决hash冲突的方法 (累计阅读 12,620)
  6. 一个大二学生有关如何成为一名软件工程师的疑问及答复 (累计阅读 9,158)
  7. 最常见的电话号码 (累计阅读 8,864)
  8. Java程序员应该知道的10个eclipse调试技巧 (累计阅读 7,983)
  9. 如何让员工忠于公司? (累计阅读 7,914)
  10. Java技术路线 (累计阅读 7,709)