1. 

Bits类是default类型的并非public类型,所以Bits类仅仅只能被IO包下的类所引用

构造方法无参数 所有方法都为静态方法,所以可以直接通过类名去访问其下的所有方法

2. 源码

/**
   Utility methods for packing/unpacking primitive values in/out of byte arrays
   using big-endian byte ordering.

 一种对字节数组高效的封装和解封手段
  使用大端字节序

 这里我们解释一下什么叫大端字节序?
 字节序为大于一个字节大小的数据在内存中的存储顺序(你可以理解为字节为内存最小单元的大小),
 一般来说一个数据的存储空间在内存中是相邻的,对于CPU读取时,需要辨别多个存储单元所存储数据的顺序,
 顺序错了可能会得到完全不一样的数据。
 一般读取方式为顺序读取,分为两种,大端字节序(big-endian)和小端字节序(little-endian),
 其中大端模式跟正常人类的阅读模式一样 从高地址忘低地址读(从左往右)
 大端模式:数据的高位存储在低地址处,低位存储在高地址处
 小端模式:数据的高位储存在高地址处,低位存储在低地址处
  */
public class Bits {

    /*
       Methods for unpacking primitive values from byte arrays starting at
       given offsets.
       
       从给定偏移量开始从字节数组中解压缩原始值的方法
       
     */

    static boolean getBoolean(byte[] b, int off) {
        return b[off] != 0;
    }

    static char getChar(byte[] b, int off) {
        return (char) ((b[off + 1] & 0xFF) +
                (b[off] << 8));
    }

    static short getShort(byte[] b, int off) {
        return (short) ((b[off + 1] & 0xFF) +
                (b[off] << 8));
    }

    static int getInt(byte[] b, int off) {
        return ((b[off + 3] & 0xFF)      ) +
                ((b[off + 2] & 0xFF) <<  8) +
                ((b[off + 1] & 0xFF) << 16) +
                ((b[off    ]       ) << 24);
    }

    static float getFloat(byte[] b, int off) {
        return Float.intBitsToFloat(getInt(b, off));
    }

    static long getLong(byte[] b, int off) {
        return ((b[off + 7] & 0xFFL)      ) +
                ((b[off + 6] & 0xFFL) <<  8) +
                ((b[off + 5] & 0xFFL) << 16) +
                ((b[off + 4] & 0xFFL) << 24) +
                ((b[off + 3] & 0xFFL) << 32) +
                ((b[off + 2] & 0xFFL) << 40) +
                ((b[off + 1] & 0xFFL) << 48) +
                (((long) b[off])      << 56);
    }

    static double getDouble(byte[] b, int off) {
        return Double.longBitsToDouble(getLong(b, off));
    }

    /*
       Methods for packing primitive values into byte arrays starting at given
       offsets.

       将原始值打包到以给定偏移量开始的字节数组的方法。
     */

    static void putBoolean(byte[] b, int off, boolean val) {
        b[off] = (byte) (val ? 1 : 0);
    }

    static void putChar(byte[] b, int off, char val) {
        b[off + 1] = (byte) (val      );
        b[off    ] = (byte) (val >>> 8);
    }

    static void putShort(byte[] b, int off, short val) {
        b[off + 1] = (byte) (val      );
        b[off    ] = (byte) (val >>> 8);
    }

    static void putInt(byte[] b, int off, int val) {
        b[off + 3] = (byte) (val       );
        b[off + 2] = (byte) (val >>>  8);
        b[off + 1] = (byte) (val >>> 16);
        b[off    ] = (byte) (val >>> 24);
    }

    static void putFloat(byte[] b, int off, float val) {
        putInt(b, off,  Float.floatToIntBits(val));
    }

    static void putLong(byte[] b, int off, long val) {
        b[off + 7] = (byte) (val       );
        b[off + 6] = (byte) (val >>>  8);
        b[off + 5] = (byte) (val >>> 16);
        b[off + 4] = (byte) (val >>> 24);
        b[off + 3] = (byte) (val >>> 32);
        b[off + 2] = (byte) (val >>> 40);
        b[off + 1] = (byte) (val >>> 48);
        b[off    ] = (byte) (val >>> 56);
    }

    static void putDouble(byte[] b, int off, double val) {
        putLong(b, off, Double.doubleToLongBits(val));
    }
}

 

3. 

get方法为获得字节数组中第“off”位数据的方法,数据类型即为返回值类型
(将其类型转换,字节型转化为对应类型),比如char型大小为两个字节,
则getchar方法将“off”位和“off+1”位的二进制流合成一个16位的二进制编码
(依照大端模式排序)然后char转换并返回;int是四个字节,
所以需要“off”位到“off+3”位合成一个32位的编码然后转化并返回;其余方法同理。



put方法则是将val数据插入到字节数组中“off”位,过程为get方法的逆过程,
以putchar为例:先将val转化为二进制码,然后将其拆分为两个字节放置在“off”位和“off+1”位上
(同样依照大端模式)

 

4. 测试

@Test
    public void test01(){
        System.out.println(Bits.getBoolean("abc".getBytes(), 0)); //true
        byte[] bytes = "abc".getBytes();
        System.out.println(bytes[0]);//97
    }
    @Test
    public void test02(){
        System.out.println(Bits.getChar("abc".getBytes(), 0)); //慢
/*        return (char) ((b[off + 1] & 0xFF) +
                (b[off] << 8));*/
        byte[] bytes = "abc".getBytes();  
        // 0xFF  == 255
        System.out.println(bytes[0 + 1] & 0xFF); //98
        System.out.println(bytes[0] << 8);       //24832
    }