Serializable的重要性及应用场景

在软件测试中,有同学提到了某些字段在程序刚运行时导致jvm激增的问题,这引起了我的注意。

MybatisPlus Generator自动生成的entity中经常带有Serializable。在开发中,VO和DTO通常是直接复制对应的entity。因此,保不齐VO等对象也保留了这个标记。我意识到之前学过这个知识,但已经遗忘,因此在此进行复习。

对于Serializable接口,它是一个标记接口,没有任何方法定义。它的存在只是为了告诉JVM某个类的实例是可以被序列化的。序列化的主要用途包括持久化、传输和缓存。

而关于serialVersionUID,是一个静态、最终的长整型字段,用于标识序列化的版本。其作用包括版本控制,避免因类的微小变动导致的反序列化失败。

对于不同的序列化机制,如JSON序列化、数据库存储以及其他的自定义序列化方案,serialVersionUID 并不起作用。

在使用JSON进行序列化和反序列化时,serialVersionUID 并不起作用。因为JSON序列化器将对象转换为JSON字符串,并不保留Java类的版本信息。

当使用Redis进行数据存储时,通常也会使用JSON字符串进行序列化和反序列化。因为Redis保存的是序列化后的数据字符串,而不是Java对象本身,因此 serialVersionUID 并不起作用。

对于MySQL等关系型数据库,当对象被存储时,ORM(如MyBatis、Hibernate)会将对象的字段提取出来并生成相应的SQL语句进行存储和查询。在这种情况下,对象序列化是由ORM框架处理的,serialVersionUID 也并不起作用。

在实现一个OJ系统中,我遇到了一个类似GitHub、leetcode的提交记录情况,需要存储在后端中。最终我选择了hash结合一定的编码来处理数据,考虑到通常展示的365个天数的提交记录应该也不会很耗时间,又能具有准确性。

对于这种情况,原本我打算使用redis来存储。在序列化到redis之后,却发现countminSketch没有任何变化。在这次测试中,hash在时间消耗上差距并不大,所以最终选择了hash。

每个serialVersionUID都是静态且final修饰,不会被GC所清理,也不会特别消耗空间,除非类爆炸现象。因此,有必要保留这些标记,毕竟难免可能之后会用到

热门手游下载