距离上一次更新该文章已经过了 698 天,文章所描述的內容可能已经发生变化,请留意。
首先,如果对象需要网络传输或者持久化(我的理解是dto和entity/model),那么就需要实现Serializable接口。为了防止反序列失败,该对象需提供一个默认的serialVersionUID(该值在反序列化的时候会进行校验,
如果校验失败会抛异常-InvalidClassException)。
但如果只是转换为json字符串的形式与网络打交道(比如MVC中前后端分离情况下,返回json-response给前端),那么这个response对象就不需要实现Serializable接口。
关于UID
serialVersionUID有两种显式的生成方式:
plaintext1
2一个是默认的1L
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,如果没有显式地定义一个名为serialVersionUID的long型的变量,编译器在编译的时候也会根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,这就决定了这个类在序列化上一定不是向前兼容的
使用默认计算的serialVersionUID就会有一个明显的劣势
plaintext1
2
3
4使用默认计算的serialVersionUID就会有一个明显的劣势,那就是类一旦序列化后,
我们就不能修改该类了,因为计算的serialVersionUID会改变,导致后期反序列话失败。
为了避免以上情况,我们手动定义一个静态常量来人为定义serialVersionUID,因为一旦手动定义了,
虚拟机就不会再进行计算了通常关于序列相关的代码,最常遇到的bug就是InvalidClassException,大概率就是因为没有显示声明UID,导致反序列化报错
总结
plaintext
1 | 1. entity/model和dto必须实现Serializable |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 小五的个人杂货铺!