在 Java 中将字节数组转换为整数,反之亦然
2022-08-31 07:06:10
我想在Java中将一些数据存储到字节数组中。基本上只是每个数字最多可以占用2个字节的数字。
我想知道如何将整数转换为2字节长字节数组,反之亦然。我在谷歌上发现了很多解决方案,但其中大多数都没有解释代码中发生的事情。有很多我不真正理解的不断变化的东西,所以我很感激一个基本的解释。
我想在Java中将一些数据存储到字节数组中。基本上只是每个数字最多可以占用2个字节的数字。
我想知道如何将整数转换为2字节长字节数组,反之亦然。我在谷歌上发现了很多解决方案,但其中大多数都没有解释代码中发生的事情。有很多我不真正理解的不断变化的东西,所以我很感激一个基本的解释。
使用在 java.nio
命名空间中找到的类,特别是 ByteBuffer
。它可以为您完成所有工作。
byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1
ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }
byte[] toByteArray(int value) {
return ByteBuffer.allocate(4).putInt(value).array();
}
byte[] toByteArray(int value) {
return new byte[] {
(byte)(value >> 24),
(byte)(value >> 16),
(byte)(value >> 8),
(byte)value };
}
int fromByteArray(byte[] bytes) {
return ByteBuffer.wrap(bytes).getInt();
}
// packing an array of 4 bytes to an int, big endian, minimal parentheses
// operator precedence: <<, &, |
// when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right
int fromByteArray(byte[] bytes) {
return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}
// packing an array of 4 bytes to an int, big endian, clean code
int fromByteArray(byte[] bytes) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8 ) |
((bytes[3] & 0xFF) << 0 );
}
将签名字节打包到 int 中时,需要将每个字节屏蔽掉,因为由于算术提升规则(如 JLS、转换和升级中所述),它被符号扩展为 32 位(而不是零扩展)。
在Joshua Bloch和Neal Gafter的Java Puzzlers(“A Big Delight in Every Byte”)中描述了一个有趣的谜题。将字节值与 int 值进行比较时,将该字节符号扩展为 int,然后将此值与另一个 int 进行比较
byte[] bytes = (…)
if (bytes[0] == 0xFF) {
// dead code, bytes[0] is in the range [-128,127] and thus never equal to 255
}
请注意,所有数值类型都在 Java 中签名,但 char 是 16 位无符号整数类型除外。