为什么如此高效?解密kryo各个数据类型的序列化编码机制,强( 七 )
EnumSet是一个专为枚举设计的集合类 , EnumSet中的所有元素都必须是指定枚举类型的枚举值 。 在序列化EnumSet时 , 需要将EnumSet中存储的枚举类型进行序列化 , 然后再序列每一个枚举值 。
序列化过程:
代码@ 1:如果序列化的EnumSet为空 , 则通过代码EnumSet.complementOf方法创建一个其元素类型与指定EnumSet里元素类型相同的EnumSet集合 , 新EnumSet集合包含原EnumSet集合所不包含的 , 此类枚举-举类剩下的枚举值(即新EnumSet集合和原EnumSet集合的集合元素加起来是该枚举类的所有枚举值) 。
代码@ 3:首先序列化EnumSet中的枚举类型类实例 , 并获取枚举类型对应的序列器 。
代码@ 4:序列化EnumSet中元素的个数 。
代码@ 5:逐一序列化EnumSet中元素(一个个枚举值) 。
16 , StringBuffer序列化实现类为DefaultSerializers $ StringBufferSerializer , 序列化:与String序列化一致 。
17 , StringBuilder序列化实现类为DefaultSerializers $ StringBuilderSerializer , 序列化:与String序列化一致 。
18 , TreeMap序列化实现类为:DefaultSerializers $ TreeMapSerializer
static public class TreeMapSerializer extends MapSerializer { public void write (Kryo kryo, Output output, Map map) {TreeMap treeMap = (TreeMap)map;kryo.writeClassAndObject(output, treeMap.comparator());super.write(kryo, output, map); }//...省略部分代码}TreeMap的序列 , 首先 , 先序列化TreeMap的比较器 , 然后再序列化TreeMap中的数据 。
序列化数据请看MapSerializer MapSerializer#write
public void write (Kryo kryo, Output output, Map map) {int length = map.size();output.writeInt(length, true);Serializer keySerializer = this.keySerializer;if (keyGenericType != null) {if (keySerializer == null) keySerializer = kryo.getSerializer(keyGenericType);keyGenericType = null;}Serializer valueSerializer = this.valueSerializer;if (valueGenericType != null) {if (valueSerializer == null) valueSerializer = kryo.getSerializer(valueGenericType);valueGenericType = null;}for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {Entry entry = (Entry)iter.next();if (keySerializer != null) {if (keysCanBeNull)kryo.writeObjectOrNull(output, entry.getKey(), keySerializer);elsekryo.writeObject(output, entry.getKey(), keySerializer);} elsekryo.writeClassAndObject(output, entry.getKey());if (valueSerializer != null) {if (valuesCanBeNull)kryo.writeObjectOrNull(output, entry.getValue(), valueSerializer);elsekryo.writeObject(output, entry.getValue(), valueSerializer);} elsekryo.writeClassAndObject(output, entry.getValue());} 复制代码其序列化方法就是遍历Map中的元素 , 调用Kryo#writeClassAndObject进行序列化 , Kryo#writeClassAndObject涉及到Kryo整个序列化流程 , 将在下节介绍 。
本节就认为到这里了 , 本节详细分析了Kryo对各种数据类型的序列化机制 , 其再降低序列化大小方面做了如下优化:-
- Kryo序列化的“对象”是数据以及少量元信息 , 这和JAVA默认的序列化的本质区别 , java默认的序列化的目的是语言层次的 , 将类 , 对象的所有信息都序列化了 , 也就是就算是不加载类的定义 , 也可以根据序列化后的信息动态生成类的所有信息 。 而Kryo反序列化时 , 必须能加载类的定义 , 这样Kryo可以节省大量的字节空间 。
- 使用变长int , 变长long存储int , long类型 , 大大节省空间 。
- 元数据(字符串类型)使用缓存机制 , 重复出现的字符串使用int来存储 , 节省存储空间 。
- 字符串类型使用UTF-8存储 , 但会使用ascii码进一步优化空间 。
- 看不上|为什么还有用户看不上华为Mate40系列来看看内行人怎么说
- 设置|iPhone拍照小技巧:保留常用设置更高效
- 制药领域|为什么AI制药这么火,为什么是现在?
- 手机壳里头|为什么要在手机壳里面夹钱?10个有9个不懂,我才知道大有讲究
- 短视频|全球最火APP?抖音爆火背后离不开这几剂“猛药”为什么抖音能够这么火?
- 电商快递|包邮不香吗,为什么还有人加49元让小哥穿西装专车送快递?
- 团队|为什么项目管理非常重要?
- 猫腻|为什么拼多多上商品价格那么便宜还包邮?有什么猫腻?看完明白了
- 加拿大|上演戏剧性一幕!iPhone12最新售价确定,苹果也没想到降价如此快
- 刷机|前几年满大街的“刷机”服务去哪里了,为什么大家都不爱刷机了?
