0xFF 是什么?

我们经常会看到在代码的基本数据类型转换时出现这样的代码

byte b = -1;
int a = b & 0xFF;

这个 0xFF 的用意是什么呢, 跟 int a = b; 又有什么区别?

数值与数据

在计算机程序里, 数值与数据是两个不同的概念. 数值表示一个数表示的大小, 例如 int 的 -1 和 byte 的 -1, 代表的是数学上的数值大小. 但是作为数据来讲, 他们两个却是不一样的

int 的 -1 的二进制表示: 11111111111111111111111111111111
byte 的 -1 的二进制表示: 11111111

基本数据类型转换

那么回到刚才的问题, int a = b & 0xFF 是什么意思?

0xFF = 00000000000000000000000011111111

也就是说 0xFF 代表了一个 byte 位全为 1.
那么

int a = b & 0xFF = 00000000000000000000000011111111 & 00000000000000000000000011111111 = 00000000000000000000000011111111 = 255

int a = b = -1 = 11111111111111111111111111111111;

至此, 我们可以看出区别, 前者保证了数据一致性, 但是数值从 -1 变成了 255, 而后者则保证了数值一致性, 都是 -1, 但是数据发生了变化.

0xFF 的应用

所以, 0xFF 这个东西, 一般用于我们做小基本数据类型转大基本数据类型. 例如我们需要序列化及反序列化 int 数据

public static void writeFixedInt(OutputStream out, int i) {
    out.write((byte) (i >>> 24));
    out.write((byte) (i >>> 16));
    out.write((byte) (i >>> 8));
    out.write((byte) i);
}

在序列化 int 时, 我们将 int 从高位到低位的每个字节一次写入 stream

public static int readFixedInt(ByteData data, long position) {
    int s = 0;
    int len = 4;
    for (int i = 0; i < len; i++) {
        s |= (data.get(position + i) & 0xFF) << ((len - i - 1) * 8);
    }
    return s;
}

而在反序列化时, 则是一次将 int 的高位字节读出来, 因为读出来的是 byte 类型, 在转为 int 类形时就需要注意保持数据一致性, 所以需要用到 0xFF, 然后再把高位数据左移, 最后拼接出完整的 int.