-------------------android培训、 java培训、期待与您交流!-------------------

对象序列化

对象序列化的目的是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制运行把内存中的Java对象转换成平台无关的二进制流,从而允许把这个二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另一个网络节点。其他程序一旦获得了这个二进制流,都可以将这种二进制流恢复成原来的Java对象。

对象序列化将一个Java对象写入IO流中,对象的反序列化则是从IO流中恢复该Java对象。

Java对象实现序列化的方式:

(1)实现Serializaable接口,该接口是一个标记接口,实现该接口无须实现任何方法,它只是表明该类的实例是可以序列化的。

(2)实现Externalizable接口,

使用对象流实现序列化

通过对象流实现序列化的步骤:

(1)创建一个ObjectOutputStream输出流。

(2)调用OjbectOutputStream对象的writeObject方法输出可序列化对象。

实例:

public classSerializableTest{ public static void main(String[] args){ ObjectOutputStream oos = null;try{ oos = new ObjectOutputStream(newFileOutputStream("e:\\test.txt")); Person p = new Person("Android",7); // 将p对象写入输出流 oos.writeObject(p); }catch (IOException e){ e.printStackTrace(); }finally{ if (oos != null){ try{ oos.close(); }catch (IOException e){ e.printStackTrace(); } } } } }   class Personimplements Serializable{ private String name; private int age; public Person(String name, int age){ super(); this.name = name; this.age = age; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public int getAge(){ return age; } public void setAge(int age){ this.age = age; } }  

反序列化的步骤:

(1)创建一个ObjectInputStream输入流。

(2)调用ObjectInputStream对象的readObject方法读取流中的对象。该方法返回一个Object类型的java对象。

实例:

public static void main(String[] args) { ObjectInputStream ois = null; try { //创建一个ObjectInputStream输出流 ois = new ObjectInputStream(newFileInputStream("e:\\test.txt")); //从流中读取一个java对象 Person p = (Person)ois.readObject(); System.out.println("name=" + p.getName() + "  ,age=" + p.getAge()); } catch (IOException e) { // TODO Auto-generated catchblock e.printStackTrace();  } catch (ClassNotFoundException e){ // TODO Auto-generated catchblock e.printStackTrace(); } finally { if (ois != null) { try { ois.close(); } catch (IOException e) { // TODO Auto-generatedcatch block e.printStackTrace(); } } } }  

反序列化机制无须通过构造器来初始化Java对象。如果反序列化某个子类实例时,反序列化机制需要恢复其关联的父类实例,恢复这些父类实例有两种方式:使用反序列化机制;使用父类无参数的构造函数。

如果一个可序列化类有多个父类(直接父类或间接父类),则该类的所有父类要么是可序列化的,要么有无参数的构造器,否则序列化时抛出IvaalidClassException异常。

对象引用的序列化

当程序序列化一个对象时,如果该对象持有一个其他对象的引用,为了在反序列化时可以正常恢复该对象,则程序会顺便把他引用的其他对象也进行序列化,否则该对象不能进行序列化。

Java序列化机制采用了一种特殊的序列化算法,其内容如下:

(1)所有保存到磁盘中的对象都有一个序列化编号。

(2)当程序试图序列化一个对象时,程序将先检测该对象是否已经序列化过,只有当该对象从未被序列化过,系统才会将该对象转换成字节序列并输出。

(3)如果某个对象是已经序列化过的,程序将直接只输出一个序列化编号,而不是再次重新序列化该对象。

注意:当使用Java序列化机制序列化可变对象时,一定要注意,只有当第一次调用wirteObject方法来输出对象时才会将对象转换为字节序列,并写出到ObjectOutputStream;在后面程序中,如果该对象的属性发送改变,即再次调用wirteObject方法输出该对象时,改变后的属性不会被输出。

自定义序列化

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

通过在属性前加transient关键字,可以指定Java序列化时无须理会该属性,transient关键字只能用来修饰属性,不可以修饰Java程序中其他部分。比如: private  transient int  age;

但使用transient关键字修饰属性虽然很简单方便,但被transient修饰的属性将被完全隔离在序列化机制之外,这样导致在反序列化恢复Java对象时无法获得该属性值。Java提供了一种自定义序列化机制,通过这种自定义序列化机制可以让程序控制如何序列化各属性,甚至完全不序列化某些属性。

自定义序列化需要对如下个方法进行处理

(1)private  void  writeObject(java.io.ObjectOutputStream out) throws IOException;

(2)private  void readObject(java.io.ObjectInputStream  in) throwsIOException,ClassNotFoundException;

(3)private  void  readObjectNoData()throwsObjectStreamException;

writeObject方法负责写入特定类的实例的状态,以便相应的readObject方法可以恢复它。通过重写该方法,程序员可以完全获得对序列化机制的控制,程序员可以自主决定那些属性需要序列化,需要怎样序列化。默认情况下,该方法会调用out.defaultWriteObject来保存Java对象的各属性,从而可以实现序列化Java对象状态的目的。

readObject方法负责从流中读取并恢复对象属性,通过重写该方法,程序员可以完全获得对反序列化机制的控制,可以自主决定需要反序列化那些属性,以及进行怎样的反序列化。默认情况下,该方法会调用in.defaultReadObject来恢复Java对象的非静态属性,通常情况下readObject方法与readObject对应,如果writeObject方法中对Java对象的属性进行了一些处理,则应该在readObject方法中对该属性进行相应的反处理,以便正确恢复该对象。

当序列化流不完整时,readObjectNoData方法可以用来正确地初始化反序列化的对象。

Externalizable自定义序列化机制

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

Externalizable接口定义的两个方法:

(1)void   readExternal(ObjectInput  in):需要序列化的类实现readExternal方法来实现反序列化。该方法调用DataInput(它是ObjectInput的父接口)的方法来恢复基本类似的属性值,调用ObjectInput的readObject方法来恢复引用类型的属性值。

(2)void   writeExternal(ObjectOutput  out):需要序列化的类实现writeExternal方法来保存对象的状态,该方法调用DataInput(它是ObjectInput的父接口)的方法来保存基本类型的属性值,,调用ObjectOutput的writeObject方法来保存引用类型的属性值。

-------------------android培训、 java培训、期待与您交流!-------------------

黑马程序员 对象序列化相关推荐

  1. 黑马程序员-Java教程-10缓冲流、转换流、序列化流

    day10[缓冲流.转换流.序列化流.打印流] 主要内容 缓冲流 转换流 序列化流 打印流 教学目标 能够使用字节缓冲流读取数据到程序 能够使用字节缓冲流写出数据到文件 能够明确字符缓冲流的作用和基本 ...

  2. 黑马程序员 oc对象的方法成员变量

    -----------黑马程序员 IOS培训.Android培训.Java培训.期待与您交流---------------- #import <Foundation/Foundation.h&g ...

  3. 【黑马程序员 C++教程从0到1入门编程】【笔记4】C++核心编程(类和对象——封装、权限、对象的初始化和清理、构造函数、析构函数、深拷贝、浅拷贝、初始化列表、友元friend、运算符重载)

    黑马程序员C++教程 文章目录 4 类和对象(类属性[成员属性],类函数[成员函数]) 4.1 封装 4.1.1 封装的意义(三种权限:public公共.protected保护.private私有)( ...

  4. [黑马程序员C++笔记]P99-P104类和对象-封装

    视频地址:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili 目录 P99类和对象-封装-属性和行为作为整体 P100类和对象-封装-案例-设计学生类 P101 ...

  5. 【黑马程序员pink老师前端】JavaScript对象

    java 学习笔记指路 基础知识 Python转java补充知识 Java中常见的名词解释 前端 [黑马程序员pink老师前端]HTML [黑马程序员pink老师前端]JavaScript基础大总结 ...

  6. 黑马程序员入学Java知识——精华总结

    黑马程序员入学Java知识--精华总结 J2SE部分,Java高新技术部分,7K面试题部分等黑马入学要求的知识点总结! 一.黑马程序员-java概述与基础知识 6 1.何为编程? 6 2.Java语言 ...

  7. 黑马程序员:Java基础总结----Java语言编程规范

       黑马程序员:Java基础总结        Java语言编程规范:参考自SUN公司文档  ASP.Net+Android+IO开发..Net培训.期待与您交流!  I.   排版规范 A.  规 ...

  8. 黑马程序员——总集篇

    -----------android培训.java培训.java学习型技术博客.期待与您交流!------------ 本人编写技术博客的时候只是针对章节的一些比较重要的知识点来编写的: 个人感觉质量 ...

  9. Ajax【黑马程序员】

    目录 1.客户端 与 服务器 1.1 服务器:存放和对外提供资源 1.2 客户端:获取和消费资源 ​编辑 2.URL地址 2.1 URL地址的概念(统一资源定位符) 2.2 URL地址的组成部分 ① ...

最新文章

  1. leetcode前缀树java_LeetCode 实现 Trie (前缀树)
  2. HDU2586(ST表+dfs)
  3. Django从理论到实战(part43)--HttpResponse对象
  4. [工具库]JOJSONBuilder工具类——一键把多个bean对象数据转换为JSON格式数据
  5. 4.2)深度卷积网络:实例研究
  6. 【个人笔记】OpenCV4 C++ 快速入门 29课
  7. CF55D: Beautiful Number
  8. js读取excel数据
  9. 快播资源地址转百度影音地址v1.2
  10. [GIS教程] 5.3 空间数据组织
  11. “特困生”卷出睡眠市场,疯狂氪金能不能氪出“好故事”?
  12. 【python数据分析】分组聚合操作
  13. 战胜拖延症的利器—Product Backlog
  14. 如何用【测试思维】做“支付功能”测试?
  15. 相对定位的元素会在原先的地方
  16. PostGIS官方教程汇总目录
  17. Android一周时间早中晚排班表
  18. Jetson 基本笔录
  19. 阿里云域名网站https申请,ssl续签设置图文教程
  20. Leetcode 592. 分数加减运算 C++

热门文章

  1. 手把手教你实现MVVM架构
  2. 模板匹配综述-SSD,BBS,DDIS,CoTM,QATM
  3. cad,3dmax,vray,photoshop
  4. 如何推广一个新的App软件
  5. 模仿淘宝手机号码输入框
  6. 研发内控平台设计简介
  7. 关于STL中的greaterT()和lessT()
  8. 上层点云分割(C++PCL)
  9. db2替换激活永久lic
  10. Kong API网关使用笔记