1. int 转 byte[ ]

/**
     * 将int转为低字节在前,高字节在后的byte数组
     */
    public static byte[] intToArrayByLow(int n) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (n & 0xff);
        bytes[1] = (byte) (n >>> 8 & 0xff);
        bytes[2] = (byte) (n >>> 16 & 0xff);
        bytes[3] = (byte) (n >>> 24 & 0xff);
        return bytes;
    }

说明:

  • & 0xff (与运算):
  • 两个 bit(1 或 0)进行与运算时,如果两者都为 1,结果为 1,否则为 0,
  • 而 0xff 转化为 2 进制为:0000000011111111,
  • 当一个 int 和 0xff 进行与运算时,即表示提取这个 int 的最低八位。 例如:
int a = 10000;// a的二进制为 10011100010000
int b =  a & 0xff;// a和0xff 与运算后,b的二进制为 10000,即十进制的16
System.out.println("b的十进制="+b);// 输出16
  • n >>> 8(位运算): >>8 表示右移 8 位,如果该数为正,则高位补 0,若为负数,则高位补 1;

例如:

1. res = 20 >> 2;
20的二进制为 0001 0100,右移2位后为 0000 0101,则结果就为 res = 5;
 
2. res = -20 >> 2;
-20的二进制为其正数的补码加1,即 11111111111111111111111111101100
右移2位后为 11111111111111111111111111111011,结果为 res = -5;
 
3. 而对于>>>符号而言:
不管正负,都是右移后高位补0;
res = 20 >>> 2; 的结果与 20>>2 相同;
res = -20 >>> 2;
-20的二进制为 1110 1011,右移2位,为111010 ,此时高位补0,即 0011 1010

所以 bytes[1] = (byte) (n >>> 8 & 0xff); 表示 先右移 8 位,然后取最低的八位。 也即从右到左, 取第 9 到 16 位

  • 再特别说明一点,上面的转换方法是采用低字节在前的方式,一开始接触的时候看着各种协议文档写着 “低字节在前”,根本不知道是什么意思。 这里解释一下低字节在前的意思,打个比方,咱们不是说 int 有 4 个字节吗? 那转成 byte 数组就是 byte[4] 对吧? byte[4]下标从 0 开始到 3,0 为前面,3 为后面。 int 的 4 个字节,最右边的是最低字节,最左边的是最高字节。 那么低字节在前的意思就是最右边的字节存在 byte[0], 最左边的字节存储在 byte[3]

2. byte[] 转 int

/**
     * 低字节在前的方式获取int值
     */
    public static int getInt(byte[] b, int offset) {
        int n = 0;
        int len = b.length;
        if (len >= offset + 4) {
            // 低字节在前
            int byte0 = b[offset] & 0xff; // 最右边的字节,不需要移位
            int byte1 = b[offset + 1] & 0xff;// 右边第二个字节,需要左移一个字节,8位
            int byte2 = b[offset + 2] & 0xff;// 右边第三个字节,需要左移两个字节,16位
            int byte3 = b[offset + 3] & 0xff;// 最左边的字节,需要左移三哥字节,24位
            n = byte0 | byte1 << 8 | byte2 << 16 | byte3 << 24;
        }
        return n;
    }

上面的代码中,为什么需要对每个字节进行 & 0xff 运算呢? 不懂的同学可以参考下面的链接学习一下。 https://blog.csdn.net/iblade/article/details/73289831

3. short 转 byte[]

short 转成 byte[] 其实和 int 转 byte[] 的逻辑一样,只不过 int 是四个字节,short 是两个字节。

/**
     * 将short转为低字节在前,高字节在后的byte数组
     */
    public static byte[] shortToByteArrayByLow(short n) {
        byte[] bytes = new byte[4];
        bytes[0] = (byte) (n & 0xff);
        bytes[1] = (byte) (n >>> 8 & 0xff);
        return bytes;
    }

4. byte[] 转 short

/**
     * @param b      低字节在前
     * @param offset
     * @return
     */
    public static short getShortByLow(byte[] b, int offset) {
        short n = 0;
        int len = b.length;
        if (len >= offset + 2) {
            // 低字节在前
            int byte0 = b[offset] & 0xff; // 最右边的字节,不需要移位
            int byte1 = b[offset + 1] & 0xff;// 右边第二个字节,需要左移一个字节,8位
            n = (short) (byte0 | byte1 << 8);
        }
        return n;
    }

5.long 转 byte[]

long 转成 byte[] 其实和 int 转 byte[] 的逻辑一样,只不过 int 是四个字节,long 是八个字节。

/**
     * long转byte[8],低字节在前
     */
    public static byte[] longToByteArrayByLow(long n) {
        byte[] bytes = new byte[8];
        bytes[0] = (byte) (n & 0xff);
        bytes[1] = (byte) (n >>> 8 & 0xff);
        bytes[2] = (byte) (n >>> 16 & 0xff);
        bytes[3] = (byte) (n >>> 24 & 0xff);
        bytes[4] = (byte) (n >>> 32 & 0xff);
        bytes[5] = (byte) (n >>> 40 & 0xff);
        bytes[6] = (byte) (n >>> 48 & 0xff);
        bytes[7] = (byte) (n >>> 56 & 0xff);
        return bytes;
    }

6.byte[] 转 long

注意:要先把每个字节转成 long 类型而不是 int 类型哦,不然后面左移 32 位以上,会超出 int 的存储范围导致数据错误。

/**
     * 将byte数组转为long
     */
    public static long getLongByLow(byte[] b, int offset) {
        long n = 0;
        int len = b.length;
        if (len >= offset + 8) {
            // 低字节在前
            long byte0 = b[offset] & 0xff; // 最右边的字节,不需要移位
            long byte1 = b[offset + 1] & 0xff;// 右边第二个字节,需要左移一个字节,8位
            long byte2 = b[offset + 2] & 0xff;// 右边第三个字节,需要左移两个字节,16位
            long byte3 = b[offset + 3] & 0xff;// 最左边的字节,需要左移三哥字节,24位
            long byte4 = b[offset + 4] & 0xff;// 最左边的字节,需要左移三哥字节,32位
            long byte5 = b[offset + 5] & 0xff;// 最左边的字节,需要左移三哥字节,40位
            long byte6 = b[offset + 6] & 0xff;// 最左边的字节,需要左移三哥字节,48位
            long byte7 = b[offset + 7] & 0xff;// 最左边的字节,需要左移三哥字节,56位
            n = byte0 | byte1 << 8 | byte2 << 16 | byte3 << 24 | byte4 << 32 | byte5 << 40 | byte6 << 48 | byte7 << 56;
        }
        return n;
    }