java 序列化和反序列化笔记

 

java 序列化与反序化

.java 序列化的用途

  1. 将数据持久化到文件中

  2. 在网络上传输字节序列

  两种功能的示意图如下 :

  <!----><!----><!----> <!----> <!---->

. 实现对象序列化的条件

  1. 只有实现了 Serializable( 默认的序列化方式 ) Externalizable( 继承 Serializable 接口 , 自定义实现来控制序列化时的行为 ) 接口的类才能被序列化 .

  2.. 利用 java.io.ObjectOutputStream 类的 writeObject(Object obj) 来实现对象序列化操作 , 并将字节序列写入到到目标输出流中 . 利用它的 readObject() 方法从源输入流中读取字节流 , 再将数据反序列化成一个对象并返回该对象 .

. 通过实现 Serializable 接口序列化 . 和反序列化

   1. 如果类 A 实现了 Serializable 接口 , 则对类 A 的非 static, transient 的实例变量进行序列化和反序列化

    此方法不能控制序列化时的行为 . 以下两种方法则行 .

   2. 如果类 A 既实现了 Serializable 接口 , 又定义了 writeObject(Object obj) 方法和 readObject() 方法 , 由调用这两个方法进行序列化和反序列化 .

   3. 如果类 A 实现了 Externalizable 接口 , 由该类必须实现 writeExternal(ObjectOutput out) 方法和 readExtername() 方法 . 在这种情况下 , 将按照这两个方法进行对象的序列化和反序列化 .

. 对象序列化和对象反序列化的步骤

   对象序列化步骤 :

   1. 创建一个对象输出流

   2. 通过对象输出流的 writeObject(Object obj) 方法写对象

    :

     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filePath));//filePath: 文件路径

     out.writeObject(obj);//obj: 要写入文件的对象

   对象反序列化步骤 :

   1. 创建一个对象输入流

   2. 通过对象输入流的 readObject(j) 方法读取对象 .( 读取对象时是按照对列方式进行的 , 既先进先出 )

   :

     ObjectInputStream  in = new ObjectInputStream (new FileInputStream(filePath));

     in.readObject();// 读取对象

. 对于实现了 Serializable 接口反序列化过程

   1. 如果内存中的对象所属的类还没有加载 , 则先加载并初始化这个类 , 如果在 classpath 中找不到这个类 , 则抛出 ClassNotFoundException

   2. 在反序列化时 , 不能调用类的任何构造方法 .

   3. 如果此类引用了其他类或者关联了其他类 , 则在序列化时 , 将同时序列化它所引用的类 .

. Serializable 接口下控制序列化行为

  1. 实现 Serializable 接口 , 并提供 private void writeObject(Object obj),private void   readObject() 方法 . 如果需要默认序列化方法或者默认反序列化方法 , 则可以在这两个方法中调用 ObjectOutputStream defaultWriteObject() 方法或者 ObjectOutputStream defaultReadObject() 方法

   2. 如何确定需要用户自定义序列化方式 , 从而控制序列化的行为 , 如下所示 :

    > 确保序列化的安全性 , 对敏感信息的隐藏者加密 . 如果序列化加密 , 则反序列化时要解密 .

    > 确保对象的成员变量符合正解的约束条件

    > 优化序列化的性能 . 主要是避免过多序列化类的关联类 .

    > 便于更好地封装类的内部数据 , 确保类的接口不会被类的内部实现所约束 .

  . 实现 Externalizable 接口

    1. 实现此接口的类必须自己控制序列化和反序列化时的行为 . 因此必须实现 public void writeExternal(ObjectOutput out) 方法和 public void readExtername() 方法 . 在对实现了 Externalizable 接口的类进行反序列化时 , 会先调用类的不带参数的构造方法 , 这是有别于默认反序列化方式的 . 所以类必须要有一个 public 访问权限的不带参数的构造方法 .

  . 可序列化类的不同版本的序列化兼容性

    对于同一个类的两个不同版本 , 即便它们的序列化版本号相同 , 也不一定能兼容 . 因为兼容性不仅取决于序列化版本号 , 还取决于类的不同版本的实现细节和序列化细节 .

 

你可能感兴趣的:(java,J#)