java基础--19Java序列化(Serializable)

目录

1.何为序列化,为什么需要序列化

2.序列化的方式

3.自定义序列化

4.版本管理:


1.何为序列化,为什么需要序列化

      如果我们将对象保存到磁盘或者进行网络传输,必须将这个对象进行序列化,即实现Serializable接口,如果不进行序列化,那么保存对象到磁盘的时候会报错,即磁盘IO操作对象的时候会报错:

   说到底就是对象的格式不正确,必须通过序列化将对象的格式转换为特殊的格式才能在磁盘上面存储该对象,准确的说就是要转换成字节,转化成可以用磁盘进行存储的格式。

2.序列化的方式

    序列化的方式就是实现Serializable接口就行了,在进行序列化操作时,会判断要被序列化的类是否是Enum、Array和Serializable类型,如果都不是则直接抛出NotSerializableException。

3.自定义序列化

   自定义序列化的方式其实就是我们希望对象的某些属性不被序列化,要实现这种效果有三种办法:

    关键字:transient

     某些数据域是不可以被序列化的,这些域如果处理不当还可能会引起本地方法崩溃,java 拥有一种很简单的机制来防止这种域被序列化,就是transient关键字来修饰这个域。还有就是静态的域,静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已。

  添加writeObject和readObject方法

   Java调用ObjectOutputStream类检查其是否有私有的,无返回值的writeObject方法,如果有,其会委托该方法进行对象序列化。

  使用Externalizable实现

  使用Externalizable接口需要实现writeExternal以及readExternal方法~在writeExternal方法中,写入想要外部序列化的元素

4.版本管理:

    当存储一个对象的时候,这个对象所属的类也必须进行存储,其中这个类比较重要的描述是序列化的版本唯一的ID,他是数据域类型和方法签名的指纹,是用来做版本控制的,

  serialVersionUID,之前说过他是一个指纹,序列化系统可以读入这个类的对象的不同版本,如果只是方法发生了变化,那么在读入新的对象数据时不会有什么问题,如果数据域发生了变化,那么就可能出问题,比如新的类增加了数据域,这种情况下对象输入流将会尽力的将流对象转换成这个类当前的版本,对象输入流会去比较非瞬时和非静态的数据域,进行一一转换,如果类型不一致,对象输入流不会做类型的转换,因为这两个对象不兼容。 如果序列化存储了一个对象,然后修改了他的serialVersionUID,再反序列化回来是要失败的。

 《阿里巴巴Java开发手册》中规定,在兼容性升级中,在修改类的时候,不要修改serialVersionUID的原因。除非是完全不兼容的两个版本。所以,serialVersionUID其实是验证版本一致性的。

  一旦类实现了Serializable,就建议明确的定义一个serialVersionUID。不然在修改类的时候,就会发生异常。因为系统会默认添加serialVersionUID,序列和反序列的会不一样,导致异常的产生。

 既然是验证版本一致性的,在做版本升级的时候(非兼容性升级),记得要修改这个字段的值哦,这样可以避免序列化混乱。

       现在需要将一个对象返回给前端,那么该对象是否需要实现 Serializable接口,并提供一个默认的serialVersionUID?如果不实现会有什么影响?一般来说如果你的对象需要网络传输或者持久化(对象直接转换为字节的形式传输),那么就需要实现Serializable接口。如果只是转换为字符串的形式与网络打交道,那么就不需要实现Serializable接口。

参考文章:

https://cloud.tencent.com/developer/news/240756

https://mp.weixin.qq.com/s/KI1r7s3quzV2JTnK5wzIKA

https://my.oschina.net/wangmengjun/blog/1588096

发布了217 篇原创文章 · 获赞 70 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_37650458/article/details/101348499