java序列化

在以前的工作中经常涉及到java对象序列化/反序列化进行网络数据传输,虽然项目中使用过,但对java序列化的概念还是比较模糊,今天写下一篇文章,作为对之前欠下的知识记录。

序列化Serialization:是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程.

序列化 的应用:
    1、永久性保存对象,保存对象的字节序列到本地文件中。

    2、 通过序列化对象在网络中传递对象;
    3、通过序列化在进程间传递对象。

在java中默认使用Serializable接口实现对象的序列化,对于所有的非static,transient(瞬态)的field进行序列化/反序列化操作。所有实现Serializable序列化接口类最好自动生成序列号(serialVersionUID)。

序列号的值有两种:一种是默认的1L,另一种是根据当前类中定义的field和方法生成的64位的数值。 序列号的生成与jvm,类字段,类的方法的定义有关,如果不为需要序列化的类设置序列号,被序列化的文件或是网络传输的消息,在反序列化的过程中,可能由于反序列化端生成的序列号发生变化而导致反序列化失败。

因此为了保证我们序列化的数据可以正确的被反序列化,强烈建议创建序列化的类的时候创建序列号。序列号的主要用途是进行版本的管理,对于具有相同版本号的对象是可以进行数据的序列化和反序列化的,对于不同版本号的数据时无法进行的。在实际的使用过程中,我们的模型是需要具有向上和向下兼容的能力,例如对于老系统持久化的数据可以平滑的在新系统下使用,而对于新系统持久化的数据也可以在老系统中继续使用。

在具有相同序列号数据的反序列化过程中,对于不存在的字段自动忽略,对于存在的字段自动进行反序列化的过程。


序列化注意事项: 

    1)序列化时,只对对象的状态进行保存,而不管对象的方法;

    2)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    3)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
    4)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
        1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。

       2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。

    5)不建议内部类进行序列化,因为内部类可以获取外部类的所有的属性字段,即内部类存有外部类的引用,如果外部不能够进行序列化,将导致内部类序列化失败;当将内部类声明为static的时候,由于内部类不再保存有外部类的引用,因此内部类可以进行序列化。

    6)java序列化的过程不仅存储了需要序列化的字段信息,还会存储一些额外的信息帮助反序列化。因此可以通过定义private void readObject(InputStream)和private void writeObject(OutStream)的方式自定义对象的序列化和反序列化过程。注意自定义序列化和反序列化的过程,操作需要成对出现,如果操作的顺序不正确将会导致反序列化失败。

第一次写学习的总结,感觉好多想要说的不知道如何表达,在java的HashMap,HashSet等集合中都实现了序列化的接口并定制有序列化的反序列的方法,感觉通过学习jdk的源码是最快,最好学习知识的方法。

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值