java.io.Serializable(序列化)接口详细总结

一、前言

  本篇是我刚参加工作时写的总结,是一篇不错的科普文,若想更深一步的了解序列化相关的知识,欢迎阅读另一篇博文:序列化的魔力
  工作后做的第一个项目是电商项目。当时不会做项目,只能照猫画虎。其中一个VO类为何要实现Serializable接口一直没有理解,不实现这个Serializable,会报错。如下是随手写的一个VO类Person.java:

import java.io.Serializable;
public class Person implements Serializable {
	private static final long serialVersionUID = 1L;
	//两个属性及getter、setter方法
	private String name;
	private String age;
<span class="token keyword">public</span> String <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
	<span class="token keyword">return</span> name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
	<span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">public</span> String <span class="token function">getAge</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
	<span class="token keyword">return</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAge</span><span class="token punctuation">(</span>String age<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
	<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

二、什么是序列化、反序列化

  翻阅JDK1.8的官方开发文档,发现Serializable接口没有方法和字段,仅用于标识可序列化的VO类。不实现此接口的类的任何字段(属性)都不能序列化和反序列化。那么什么是序列化和反序列化呢?

  由于序列化和反序列化概念太抽象,还是通过两个场景来理解为上策。

  (场景一)以上面提到的Person.java为例。这个VO类中的两个字段name和age在程序运行后都在堆内存中,程序执行完毕后内存得到释放,name和age的值也不复存在。如果现在计算机要把这个类的实例发送到另一台机器、或是想保存这个VO类的实例到数据库(持久化对象),以便以后再取出来用。这时就需要对这个类进行序列化,便于传送或保存。用的时候再反序列化重新生成这个对象的实例。

  (场景二)以搬桌子为例,桌子太大了不能通过比较小的门,我们要把它拆了再运进去,这个拆桌子的过程就是序列化。同理,反序列化就是等我们需要用桌子的时候再把它组合起来,这个过程就是反序列化。

  学到这里就可以给**“序列化”下一个定义了**:
  把原本在内存中的对象状态 变成可存储或传输的过程称之为序列化。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

  序列化前的对象和反序列化后得到的对象,内容是一样的(且对象中包含的引用也相同),但两个对象的地址不同。换句话说,序列化操作可以实现对任何可Serializable对象的”深度复制(deep copy)"。

三、什么情况下需要序列化

通过上面的分析,我们不难看出,一下三种情况需要使用序列化接口:

a)当你想把的内存中的对象状态保存到一个文件中或者数据库中,以便可以在以后重新创建精确的副本;
b)当你想用套接字在网络上传送对象的时候(从一个应用程序域发送到另一个应用程序域中);
c)当你想通过RMI传输对象的时候;

 
 

    四、注意事项:

    a)序列化时,只对对象的状态进行保存,而不管对象的方法;
    b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
    d)并非所有的对象都可以序列化。
    e) 序列化会忽略静态变量,即序列化不保存静态变量的状态。静态成员属于类级别的,不能序列化。添加了static、transient关键字后的变量不能序列化。
    
     
     

      五、序列化ID

      private static final long serialVersionUID = 1L;
      
       
       

          序列化 ID在 Eclipse 下提供了两种生成策略,一个设为固定的 1L,另一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具生成)。一般如果没有特殊需求,用默认的 1L 就可以,这样可以确保反序列化成功。因为不同的序列化id之间不能进行序列化和反序列化。

        • 1
          点赞
        • 1
          收藏
          觉得还不错? 一键收藏
        • 0
          评论

        “相关推荐”对你有帮助么?

        • 非常没帮助
        • 没帮助
        • 一般
        • 有帮助
        • 非常有帮助
        提交
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

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

        抵扣说明:

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

        余额充值