序列化
什么是序列化
将一个对象转化为字节流,从而能够保存到磁盘,进行网络传输。
Java原生序列化
实现Serializable
没有任何实现,只是标志该类的对象是可序列化的。
实现Externalizable
Externalizable继承了Serializable接口,还定义了两个抽象方法:writeExternal()和readExternal(),如果开发人员使用Externalizable来实现序列化和反序列化,需要重写writeExternal()和readExternal()方法。
底层实现
底层是调用了ObjectOutputStream.writeObject方法,当然你重写了,就反射invoke你重写的方法
如果对象实现了Serializable接口,就调用writeOrdinaryObject()方法。代码是个四层if else(String,enum,Array各自有各自的执行方法)
会通过反射拿到 序列化对象的所有字段的值
serialVersionUID的作用
标明当前class的版本号。保持版本的兼容性。反序列化时会验证字节流的serialVersionUID与本地类是否相同,不同会出现序列化版本不一致的异常。如果不显示定义,会由JVM依据class的信息自动生成。对这个类编译两次,他们的serialVersionUID会不同,由此会造成反序列化报错。因此必须要显示定义serialVersionUID。idea插件可以帮助自动生成serialVersionUID。
什么字段不会参与序列化
-
final,static修饰的
-
@Transient注解修饰的
-
序列化不会关心Method,Constructor,只关心对象特有的Field。
-
socket,thread类不能也没有必要序列化。
实现序列化的四种方式:
jdk序列化:implements serializable
protobuf:编写proto文件并编译,性能高,序列化后文件小,序列化速度快,可读性差,适合rpc
xml:可读性强、但文件很大,传输性能低。
json:具有层级结构,可读性强。json比xml更简短,传输性能比xml高,更易于解析。
XML 需要使用 XML 解析器来解析,JSON 可以使用标准的 JavaScript 函数来解析。
- fastjson alibaba 有bug,不推荐
- jackson(springboot默认的序列化方式)
- gson
序列化可以实现深拷贝,浅拷贝直接clone方法即可。