java int 4个字节_将4个字节转换为int
一、背景
在Java手写JVM时,需要读取 .class
后缀的字节码文件。当把字节码文件以 byte[]
(比特数组)的形式读取到内存中时,数组前四个字节为 0xCAFEBABE
。
如何判断我读取的四个字节的值等于 0xCAFEBABE
呢?
二、单个字节转int
2.1 正确代码
public class Test {
public static void main(String[] args) {
int ca = (byte)0xca;
int fe = (byte)0xfe;
int ba = (byte)0xba;
int be = (byte)0xbe;
System.out.println(ca);
System.out.println(fe);
System.out.println(ba);
System.out.println(be);
}
}
输出结果:
-54 -2 -70 -66
2.2 错误示例
int ca = 0xca; // 值为 202
2.3 错误原因分析
0xca
转化为二进制为 11001010
int
型占4个字节:
十进制 | 二进制(双字) |
---|---|
-54 | 1111 1111 1111 1111 1111 1111 1100 1010 |
202 | 0000 0000 0000 0000 0000 0000 1100 1010 |
表格中数据的正确性,可以借助 Windows 系统的计算器来表示:
长度占1个字节的byte转化为长度为4个字节的int,高位补充和符号位相同的值,可以保持值的不变。
如果是负数,符号位为1,扩展位数时,高位补1:
负数 | 原码 | 补码 | 扩展为32位补码 | 32位原码 | 结果 |
---|---|---|---|---|---|
-54 | 1011 0110 | 1100 1010 | 1111 1111 1111 1111 1111 1111 1100 1010 | 1000 0000 0000 0000 0000 0000 0011 0110 | -54 |
但是,如果直接声明为整型,则直接把 1100 1010 作为低8位,剩余高32位全是 0。
三、字节数组转int
有了第二节的结论,我们这里可以用int来表示字节。
public class Test {
public static void main(String[] args) {
byte[] cafebabe = new byte[]{-54,-2,-70,-66};
int result = toInt(cafebabe);
System.out.println(Integer.toHexString(result));
}
private static int toInt(byte[] bytes) {
int result = 0;
for (int i = 0; i < 4; i++) {
result <<= 8;
result |= bytes[i] & 0xFF;
}
return result;
}
}
输出结果:
cafebabe
说明这里的 toInt
方法是正确的。