序列化机制允许将实现序列化的Java对象转换成字节序列 ,这些字节序列可以被保存在磁盘上,或者通过网络传输,

以备以后重新恢复成原来的对象.

1.对象的序列化(serialize)指将一个Java对象写入IO流中,对象的反序列化机制(Deserialize)则指从IO流中恢复该Java对象.

如果需要让某个对象可以支持序列化机制,必须让它的类是可序列化的(实现Serialize接口或者Externalizable接口)

一.使用对象流实现序列化

ObjectOutputStream oos=new ObjectOutputStream( new FileOutputStream("..."));//输出流(处理流)

oos.writeObject(new Object())//对象输出到输出流中

二.使用对象流反序列化

ObjectInputStream ois=new ObjectInputStream( new FileInputStream("..."));//输入流

Object obj=ois.readObject();//从IO流中读取该Java对象,完成反序列化机制

2.对象引用的序列化

1)如果某个类的基本类型是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型属性类是不可序列化的.

2)   Java序列化算法:

所有保存到磁盘的对象都有一个序列化编号,  当程序试图序列化一个对象时,程序先检查该对象是否已经被序列化过了,只有当该对象从未被序列化过,系统才会将该对象转换成字节序列并输出.  如果某个对象已经被序列化过了,程序将只是输出一个序列化编号,而不是再次重新序列化该对象.

3)由于Java的序列化机制,当程序序列胡一个可变对象时,只有第一次使用writeObject方法输出时才会将该对象转换成字节序列并输出,即使后面该对象的属性已经改变,程序再次调用writeObject方法时,只是输出一个序列化编号,所以改变的属性值不会被输出.

三.自定义序列化

当对某个对象进行序列化时,系统会自动把该对象的所有属性依次进行序列化,如果某个属性引用到另一个对象,则被引用的对象也会被序列化,如果被引用的对象属性也引用了其他对象,则被引用的对象也会被序列化,这种被称为递归序列化.

1)被transient修饰的属性,Java对该属性不进行序列化.  被transient修饰的属性将被完全隔离在序列化机制外,在反序列化恢复该Java对象时无法获得该属性值.

transient关键字只能用于修饰属性,不可修饰Java中其他成分.

2)Java提供了另外一种序列化机制,通过这种自定义序列化机制可以让程序控制如何序列化各属性,甚至完全不序列化某些属性.

//上述代码为自定义序列化

writeObject方法负责写入特定类的实例状态, 以便相应的readObject可以恢复它. 通过重写该方法, 可以完全获得对序列化机制的控制.(可以自主决定哪些属性需要序列化,如何序列化)

readObject方法负责从流中读取并恢复对象属性, 通过重写该方法, 可以完全获得对反序列化机制的控制,(自主决定需要反序列化哪些属性,如何反序列化)

<注意>当序列化流不完整时, readObjectNoData 方法可以用来正确地初始化反序列化对象, 例如,当接收方使用的反序列化类的版本不同于发送方, 或者序列化流被篡改时, 系统都会调用 readObjectNoData 方法来初始化反序列化对象.

writeObject 方法存储属性的顺序应该和 readObject方法中恢复属性的顺序一致, 否则不能正常恢复该对象.

3)更彻底的序列化机制

如果需要在实现序列化某对象时替换该对象, 应为序列化类提供 Object writeReplace() 方法.

Java的序列化机制保证在序列化某个对象之前, 先调用该对象的 writeReplace()方法, 如果该方法返回另一个Java对象, 系统

将再次调用另一个对象的writeReplace方法, 直到该方法不再返回另一个对象为止. 程序最后将调用该对象的 writeObject 方法来保存该对象的状态.

//序列化机制在序列化Person对象时, 实际是转换为序列化 ArrayList对象

<注意>与writeReplace()方法相对的是, 序列化机制中还有一个特殊的方法, 可以实现保护性复制整个对象.

Object readResolve() 方法会紧接着readObject() 之后被调用, 该方法的返回值将会代替原来反序列化的对象, 而原来readObject 反序列化对象将会被立即丢弃.

四.使用 Externalizable 接口实现自定义序列化机制

Java提供了另一种序列化机制,这种序列化方式完全由程序员决定存储和恢复对象数据. 要实现该目标,Java类必须实现Externalizable接口.

1)Externalizable接口强制自定义序列化.

<重点>1.程序需要序列化实现Externalizable接口的对象, 一样调用ObjectOutputStream 的writeObject()方法输出该对象;反序列化该对象

,调用ObjectInputStream 的readObject()方法即可.

2.需要实现序列化的类,最好给出无参构造,否则程序会出现InvalidClassException异常.


    
五.两种序列化机制的对比

实现Serializable接口                                            实现Externalizable接口

系统自动存储必要信息                                        程序员决定存储哪些信息(自定义序列化)

Java内建支持,易于实现,只需实现该接口                提供两个空方法,实现该接口必须为两个空方法提供实现
    即可,无序任何代码支持

性能略差                                                            性能略高

<注意>虽然实现Externalizable接口能带来性能提升, 但由于该接口提升了编程的复杂度, 所以实际开发中大多使用Serializable接口来实现
序列化.

六.(重点)关于对象序列化的注意事项

1)对象的类名,属性(包括基本类型,数组,对其他对象的引用)都会被序列化; 方法, static属性(静态属性), transient属性(瞬态属性)
    都不会被序列化.

2)实现Serializable接口的类如果要想让某个属性不被序列化, 可用transient修饰该属性, 而不是用static修饰该属性.(虽然static)
    也能达到这样的效果, 但static不能这样用.

3)保证序列化对象的属性的类型也是可序列化的, 否则, 该类是不可序列化的.

4)反序列化对象时必须有对象的class文件.

5)当通过文件或者网络来读取序列化后对象时,必须按实际写入的顺序读取.

七.版本

反序列化对象时必须提供该对象的class文件, 有时随着项目的升级, 系统的class 文件也会升级, Java为了保证两个class文件的兼容性

Java序列化机制允许为序列化类提供一个private static final 的 serialVersionUID 属性值, 该属性值用于标识该Java类的序列化版本,

当一个类升级后, 只要它的serialVersionUID属性值保持不变, 序列化机制也会把它们当成同一个序列化版本.

<*>不显示定义serialVersionUID属性的另一个弊端是: 不利于在JVM之间的移植, 不同编译器计算该属性的计算策略可能不同, 即使该类

完全没有改变, 但因为JVM的不同, 也会出现序列化版本不兼容而无法正确反序列的现象.

<重点>对类的修改会导致该类反序列化失败时,应该为该类重新分配一个serialVersionUID属性值.

对类的哪些修改会导致反序列失败,分两种情况:

1)修改类时仅仅修改了方法, 静态属性或者瞬时属性, 则反序列化不受任何影响, 类定义无须修改serialVersionUID属性值.

2)如果修改了类中的非静态 , 非瞬态属性, 则可能导致序列化版本不兼容.

对象序列化的含义和意义相关推荐

  1. stream流去除对象的值_I/O流(过滤流、对象序列化、字符流)

    过滤流基础 Data Stream 首先我们来介绍一对过滤流:DataInputStream 和 DataOutputStream.这两个类有什么作用呢?首先来思考下面的需求:假设,要把一个 doub ...

  2. Java学习总结:51(对象序列化)

    对象序列化 对象序列化的本质实际上就是将内存中所保存的对象数据转换为二进制数据流进行传输的操作. 但并不是所有类的对象都可以直接进行序列化操作,要被序列化的对象所在的类一定要实现java.io.Ser ...

  3. .NET 中的对象序列化 (转载)

    .NET 中的对象序列化 Piet Obermeyer Microsoft Corporation 2001 年 8 月 摘要:为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便 ...

  4. C#[Serializable]在C#中的作用-NET 中的对象序列化

    为什么要使用序列化?最重要的两个原因是:将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本:按值将对象从一个应用程序域发送至另一个应用程序域.例如,序列化可用于在 ASP.NET 中保 ...

  5. Java I/O中的对象序列化

    Java I/O中的对象序列化 Java对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象.利用对象的序列化,可以实现轻量级持久性 ...

  6. 你不知道的java对象序列化的秘密

    文章目录 简介 什么是序列化 重构序列化对象 序列化不是加密 使用真正的加密 使用代理 Serializable和Externalizable的区别 总结 简介 你知道序列化可以使用代理吗?你知道序列 ...

  7. java对象序列化克隆_Java8基础知识(三)对象克隆与序列化

    对象克隆 对象克隆最简单的方式是:将对原对象的引用直接传给一个新的副本变量.这种方式存在很大的缺陷,两个变量中任何一个变量的改变都会影响另一个变量. 浅拷贝 利用Object类的clone方法,能够创 ...

  8. string转成对象_详解Java I/O流(五),对象序列化

    对象序列化 什么是序列化和反序列化呢? 序列化就是将对象转成字节序列的过程,反序列化就是将字节序列重组成对象的过程. 在这里插入图片描述 为什么要有对象序列化机制 程序中的对象,其实是存在有内存中,当 ...

  9. JavaScript之对象序列化详解

    一.什么是对象序列化? 对象序列化是指将对象的状态转换为字符串(来自我这菜鸟的理解,好像有些书上也是这么说的,浅显易懂!): 序列化(Serialization)是将对象的状态信息转换为可以存储或传输 ...

最新文章

  1. 意大利_【解读】去意大利留学,一定要学意大利语吗?意大利语难吗?
  2. java画布颜色切换_在本视频讲解演示中,扩展画布的目的是为了后面制作齿孔时操作起来方便,扩展部分更换了另一种颜色,是为了以示区别,能直观区分出票面部分。...
  3. Cesium中的坐标系及转换
  4. Pandas 文本数据方法 startswith( ) endwith( )
  5. [转载]:C#两种不同的存储过程调用方法
  6. 5G格局剧变!苹果高通和解,英特尔退票出局,华为独善其身
  7. 2015年1月微信上线原创声明功能:智能添加原创标识 转载自动注明出处
  8. vs2013制作滚屏软件
  9. 看单片机原理图-红外遥控、EEPROM
  10. 用三元组存储稀疏矩阵,实现其快速转置及矩阵相乘
  11. 阿里玄难:面向不确定性的软件设计几点思考
  12. 汽车电器设备与维修【1】
  13. 一位尚德机构网课老师的一天:从容、热爱与“一键全连”
  14. java毕业生设计运动会成绩管理系统计算机源码+系统+mysql+调试部署+lw
  15. nginx-GET /favicon.ico HTTP/1.1
  16. WIN10 注册.dll regsvr32.exe错误 VC6添加插件
  17. 2020知道答案C语言,C语言及逆向2020知到答案
  18. c语言中static作用
  19. Web全栈 第九周-曾老师-专题视频课程
  20. MAP地图采集制作学习路线

热门文章

  1. 高德地图荣获2016金瑞奖“最具成长力产品奖”
  2. Docker容器部署
  3. Linux串口驱动阅读笔记
  4. 怎样才能让学生用计算机玩游戏,让孩子通过游戏就能了解电脑的计算原理!大人看了都想玩...
  5. ipad上自定义view的旋转适配
  6. Hive计算两个经纬度坐标的直线距离
  7. Thinking in Shader(1)
  8. 来让产品经理告诉你,如何有逻辑的看懂《信条》?
  9. PPPOE拨号详解——保活,断链
  10. bf难得梦见我一回,可惜。。。