JAVA——(待看)java中int与byte数组互转代码详细分析

来自 <https://www.ktanx.com/blog/p/200

在 java 中,可能会遇到将 int 转成 byte[] 数组,或者将 byte[] 数组转成 int 的情况。下面我们来思考下怎么实现?

首先,分析 int 在 java 内存中的存储格式。

众所周知,int 类型在内存中占 4 个字节,采用补码方式存储(假如对原码、反码、补码不熟悉,请查阅相关资料)。举例:

整型 - 128 对应内存中的二进制值为

整型 128 对应内存中的二进制值为

然后,考虑如何把 int 类型 4 个字节放入 byte 数组中。

有两种可选方式:一是 int 低字节数据放置在 byte 数组低位置 (little-endian),二是 int 低字节数据放置在 byte 数组高位置 (big-endian)。两种方式都行,实际使用时,以既有约定为准。这里采用 big-endian。以整型 - 128 为例,转化后的 byte 数组为

说清转化思路后,请看实现代码,如下:

1. public static byte[] int2Bytes(int value, int len) {
2. byte[] b = new byte[len];
3. for (int i = 0; i < len; i++) {
4. b[len - i - 1] = (byte)((value >> 8 * i) & 0xff);
5. }
6. return b;
}

 

 

需要说明下位操作符 “>>”。>> 是带符号右移,使用格式为 value >> n。如果 n 大于 value 类型所占二进制位数 m 时(上例 value 为 int 类型, 则 m 为 32 位),则右移 n%m 位(% 取模操作符)。

注意:细心的读者可能会发现,在对 value 进行移位操作后,还需要跟字面量 0xff(二进制 00000000 00000000 00000000 11111111)相与,即将 value 前 3 个字节都置为 00000000,最后一个字节保存不变,思考下这步操作是否必要呢?

其实完全没必要,在将 int 强制转换成 byte 时,会自动丢弃前 3 个字节,前 3 个字节值是否全为 0,对结果完全没影响,因此与操作完全是多余的,没有任何作用且浪费了一点点程序执行效率。

修改后代码为

b[len - i - 1] = (byte)((value >> 8 * i));

下面考虑怎么将上述 byte 数组反转成 int。

我们的想法是,依次从 byte 数组中取出单个 byte,对每个 byte 通过与及左移位操作还原成对应位置的 int,最后将得各个 int 值相加汇总,即为所要的结果。文字可能没表达清楚,直接以整型 - 128 转成的数组 byte 为例,说明如何将该 byte 数组反转化为整型 - 128。

代码如下:

1. public static int bytes2Int(byte[] b, int start, int len) {
2. int sum = 0;
3. int end = start + len;
4. for (int i = start; i < end; i++) {
5. int n = ((int)b[i]) & 0xff;
6. n <<= (--len) * 8;
7. sum += n;
8. }
9. return sum;
}

 

请注意,上述代码中将 b[i] 强制转换成 int,实际上属于多余操作。在进行 & 操作时,两个操作数会先自动转换成 int 类型,因此简化版代码为

int n = b[i] & 0xff;

继续思考下上面的 & 操作是否必要呢,能不能直接改成

1. int n = b[i];

答案是不行。对于单个 byte 类型,在 java 内存中占一个字节,同样是以补码方式存储。如 byte 型变量-1(二进制值为 1111 1111), 强制转换成 int 类型后对应的二进制值为 1111 1111  1111 1111  1111 1111  1111 1111,不是我们需要的 0000 0000  0000 0000  0000 0000  1111 1111 因此需要跟 0xff 相与,以达到将前 3 个字节置为 0 的目的

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值