1,什么是序列化?
Java中的对象存在与JVM中,当JVM关闭后对象就不存在了。为了复用对象,可以将对象表示为一个字节流序列,该字节流序列被反序列化为Java对象时的数据和类型信息与被序列化之前一致。2,什么场景需要序列化?
当前的JVM需要与外接进行交互的场景。比如,使用Redis或MQ或文件存储等持久化Java对象的场景、WebService等跨系统共享对象等场景。3,序列化方法?
1、JDK自身提供了序列化Java对象的方法- 对象需要实现Serializable接口,该接口没有任何需要重写的方法。生成private static final long serialVersionUID。如果serialVersionUID不相同,为了防止反序列化对虚拟机造成伤害,反序列化错。
- 被transient关键字修饰的属性是不参与序化。
- 如果对象中有 private void writeObject(ObjectOutputStream out) 或者 private void readObject(ObjectInputStream in)的话,Serializable接口会调用该方法进行序列化与反序化。
- transient关键字、writeObject()、readObject()都是在对象实现Serializable接口的情况下效。
- 对象实现Externalizable接口,重写writeExternal(ObjectOutput out) 和 readExternal(ObjectInput in)方法来更灵活的实现序列化与反序列化。
2、JSON形式的序列化
可以使用Alibaba提供的FastJson或者Google的gson来将对象序列化为json字符串进行传输(xml字符串也可以)。特点是很直观。3、Google protostuff
Google出品,比较强大,推荐使用。支持序列化的ClassA和反序列化的ClassB可以是不同的包路径和类名,支持前后相同属性名的类型可以不同(比如int转long)。参见 特点是灵活、跨语言、效率高。4、其他工具,如 Kryo、Hessian等。
注意:
- Serializable接口反序列化时类的全路径必须相同。
- 父类实现了Serializable接口,子类可以不实现,但建议子类要拥有自己的serialVersionUID。
- 当一个对象的实例变量引用了其他对象,被引用的对象也会序列化。
- 反序列化不会改变当前JVM类的静态变量的值。
参考资料:
- 以上内容为笔者日常琐屑积累,已无从考究引用。如果有,请站内信提示。