为什么如此高效?解密kryo各个数据类型的序列化编码机制,强( 四 )
4 , 字节类型序列化实现类为:DefaultSerializers $ ByteSerializer , 序列化:直接将字节写入字节流中即可 。
5 , char类型序列化实现类为:DefaultSerializers $ CharSerializer
输出#writeChar
/** Writes a 2 byte char. Uses BIG_ENDIAN byte order. */ public void writeChar (char value) throws KryoException {require(2);buffer[position++] = (byte)(value >>> 8);buffer[position++] = (byte)value; }序列化:char在java中使用2字节存储(unicode) , kryo在序列化时 , 按大端字节的顺序 , 将char写入字节流
6 , 短类型序列化实现类为DefaultSerializers $ ShortSerializer Output#writeShort
/** Writes a 2 byte short. Uses BIG_ENDIAN byte order. */ public void writeShort (int value) throws KryoException {require(2);buffer[position++] = (byte)(value >>> 8);buffer[position++] = (byte)value; }序列化:与char类型序列化一样 , 采用大端字节顺序存储 。
7 , long类型序列化实现类为:DefaultSerializers $ LongSerializer
输出#writeLong
public int writeLong (long value, boolean optimizePositive) throws KryoException {return writeVarLong(value, optimizePositive);}序列化:采用变长字节(1-9)位来存储long , 其编码规则与int变长类型一致 , 每个字节的高位表示表示结束 , 1:表示还需要继续读取下一个字节 , 0:表示结束 。
8 , 浮点类型序列化实现类为:DefaultSerializers $ FloatSerializer
/** Writes a 4 byte float. */public void writeFloat (float value) throws KryoException { writeInt(Float.floatToIntBits(value));}/** Writes a 4 byte int. Uses BIG_ENDIAN byte order. */public void writeInt (int value) throws KryoException { require(4); byte[] buffer = this.buffer; buffer[position++] = (byte)(value >> 24); buffer[position++] = (byte)(value >> 16); buffer[position++] = (byte)(value >> 8); buffer[position++] = (byte)value;}序列化:首先将float按照IEEE 754编码标准 , 转换为int类型 , 然后按大端序列 , 使用固定长度4字节来存储float , 这里之所以不使用变长字节来存储float , 是因为使用Float .floatToIntBits(value)产生的值 , 比较大 , 基本都需要使用4个字才能存储 , 如果使用变长字节 , 则需要5个字节 , 反而消耗的存储空间大小 。
9 , DefaultSerializers $ DoubleSerializer输出#writeDouble序列化:首先将Double遵循IEEE 754编码标准转换为Long , 然后才去固定8字节存储 。 随即 , 介绍了8种基本类型(boolean , byte , char , short , int , float ,long , double)和String类型的序列化与反序列化 。
10 , BigInteger序列化实现类为:DefaultSerializers $ BigIntegerSerializer/** Writes an 8 byte double. */public void writeDouble (double value) throws KryoException { writeLong(Double.doubleToLongBits(value));}/** Writes an 8 byte long. Uses BIG_ENDIAN byte order. */public void writeLong (long value) throws KryoException { require(8); byte[] buffer = this.buffer; buffer[position++] = (byte)(value >>> 56); buffer[position++] = (byte)(value >>> 48); buffer[position++] = (byte)(value >>> 40); buffer[position++] = (byte)(value >>> 32); buffer[position++] = (byte)(value >>> 24); buffer[position++] = (byte)(value >>> 16); buffer[position++] = (byte)(value >>> 8); buffer[position++] = (byte)value;}BigInteger序列化实现 , 整体格式与String类型一样 , 由length +内容构成 。
- 如果为null , 则写入一个字节 , 其增量0 , 表示长度为0 。
- 如果为BigInteger.ZERO , 则长度写入2 , 随后再写入1个字节的内容 , 字节内容为0 , 表示ZERO 。
- 将BigInteger转换成byte []数组 , 首先写入长度=(byte长度+ 1) , 然后写入byte的内容即可 。
BigDecimal的序列化与BigInteger相同 , 首先是通过BigDecimal#unscaledValue方法返回对应的BigInteger , 然后序列化 , 在反序列化时通过BigInteger创建对应的BigDecimal即可 。
12 , 类实例序列化实现类为:DefaultSerializers $ ClassSerializer
public void write (Kryo kryo, Output output, Class object) { kryo.writeClass(output, object); // @1 output.writeByte((object != null// @2}代码@ 1:调用Kryo的writeClass方法序列化Class实例 。 代码@ 2:写入是否是包装类型(针对8种基本类型) 。接下来我们重点分析Kryo#writeClass
public Registration writeClass (Output output, Class type) {if (output == null) throw new IllegalArgumentException("output cannot be null.");try {return classResolver.writeClass(output, type);// @1} finally {if (depth == 0// @2}}代码@ 2:完成一次写入后 , 需要重置Kryo中的临时数据结构 , 这也就是kryo实例非线程安全的原因 , 其中一些重要的数据结构会 。 代码@ 1:首先调用ClassResolver.wreteClass方法 。 再ClassResolver.writeClass中详细说明 。
- 看不上|为什么还有用户看不上华为Mate40系列来看看内行人怎么说
- 设置|iPhone拍照小技巧:保留常用设置更高效
- 制药领域|为什么AI制药这么火,为什么是现在?
- 手机壳里头|为什么要在手机壳里面夹钱?10个有9个不懂,我才知道大有讲究
- 短视频|全球最火APP?抖音爆火背后离不开这几剂“猛药”为什么抖音能够这么火?
- 电商快递|包邮不香吗,为什么还有人加49元让小哥穿西装专车送快递?
- 团队|为什么项目管理非常重要?
- 猫腻|为什么拼多多上商品价格那么便宜还包邮?有什么猫腻?看完明白了
- 加拿大|上演戏剧性一幕!iPhone12最新售价确定,苹果也没想到降价如此快
- 刷机|前几年满大街的“刷机”服务去哪里了,为什么大家都不爱刷机了?
