Java对象序列化

Serializable接口

Serializable接口只是一个标记接口,不包含任何的方法。

Java的对象序列化是指将那些实现Serializable接口的对象转化成一个字节序列,并能够用这个字节序列完全恢复为原来的对象。这种序列化机制能自动弥补不同操作系统之间的差异。

序列化

对象转成字节

  1. 创建某种OutputStream,例FileOutputStream、ByteArrayOutputStream等。
  2. 用ObjectOutputStream封装使用的OutputStream。
  3. 调用writeObject()进行对象序列化。

反序列化

字节转对象

  1. 创建某种InputStream,例FileInputstream、ByteArrayInputStream等。
  2. 用ObjectInputStream封装使用的InputStream。
  3. readObject()进行反序列化。

对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构。
在进行反序列的时候,Serializable对象完全以它存储的二进制位作为基础来构造,而不调用构造器(构造方法)。

序列化前的对象与反序列还原后对象的关系

属于深度复制

  • 浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
  • 深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的所引用对象的对象都复制了一遍。

序列化前的对象与反序列还原后对象的地址不一样,而两个对象中的引用也不一样,但是值都一样。换句话说,通过序列化操作,我们可以实现对任何Serializable对象的”深度复制(deep copy)”——这意味着我们复制的是整个对象网,而不仅仅是基本对象及其引用。

对于用同一个IO流进行序列化操作的Serializable对象,他们的地址是一样的,同一对象,与用其他IO流的Serializable对象地址却不相同。
只要将对象序列化到单一流中,就可以恢复出原来对象一样的对象网,而且只要在同一流中,对象都是同一个。

serialVersionUID

UID:stream unique identifier

在Java中SerialVersionUID是唯一控制着能否反序列化成功的标志,只要这个值不一样,就无法反序列化。

向上兼容性

旧版本的Serializable对象能读取新版本的Serializable对象序列化后的数据流(二进制)。

  • 新数据流中的多余的内容将会被忽略;
  • 但是在新版本的Serializble对象中修改了老版本的Serializable对象的内容,即使UID不变,也会报异常。

向下兼容性

新版本的Serializable对象能读取旧版本的Serializable对象序列化后的数据流(二进制)。

  • 旧的数据流中包含的所包含的所有内容将会被恢复,新版本的类中没有涉及到的部分将保持默认值。
  • 对于那些没有默认值进行初始化的参数,需要进行初始化操作。
private void readObject(java.io.ObjectInputStream in) throws IOException,ClassNotFoundException{
    in.defaultReadObject();//先反序列化对象
    if(version=123){
        //初始化其他字段
    }else if(version=456){
        //初始化其他字段
    }else{
        //太老的版本不支持
        throw new InvalidClassException();
    }
}

要保证in.defaultReadObject()的执行,要求serialVersionUID保持一致,所以version不能使用serialVersionUID,version是我们预先设置的,final long version=xxxx。

保持向下兼容性的要求
1. serialVersionUID保持一致。
2. 预先设置好我们自己的版本识别标记的final long version=xxxx。
3. 保证对象的所有字段都得到了初始化。

serialVersionUID做为序列化的版本控制是一个非常有用的兼容手段,通常情况下,我们应该手工设置该值,idea或eclipse等IDE会有提示你设置其值。serialVersionUID可以任意设置,根据不同的兼容性做相应改动。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值