首页 > 编程 > Java > 正文

Java序列化

2019-11-06 06:54:29
字体:
来源:转载
供稿:网友

学习java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:523047986  我们一起学Java!

一、序列化

序列化定义:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。目的:以某种存储形式使自定义对象持久化将对象从一个地方传递到另一个地方

二、Java序列化

一个对象能够序列化的前提是实现Serializable接口。Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。如下:[java] view plain copyclass myPoint implements Serializable{  }   JAVA反序列化不会调用任何构造器序列化的控制:Externalizable。读写都交给你要在方法writeExternal写入序列化的参数要在方法readExternal读取反序列化的值要有默认的构造方法(readExternal执行完成,再执行默认的构造器)[java] view plain copyvoid writeExternal(ObjectOutput out) throws IOException;  void readExternal(ObjectInput in) throws IOException,ClassNotFoundException;  public class Point implements Externalizable {      PRivate int a;      private int b;      public Point(int a, int b) {          this.a = a;          this.b = b;      }      public Point() {      }      public String toString() {          return a + " , " + b;      }            public void writeExternal(ObjectOutput out) throws IOException {          out.write(a);          out.write(b);      }      public void readExternal(ObjectInput in) throws IOException,              ClassNotFoundException {          a = in.read();          b = in.read();      }      public static void main(String[] args) throws IOException,              ClassNotFoundException {          String file = "d://1.txt";          Point p = new Point(1, 2);          System.out.println(p);          FileOutputStream fos = new FileOutputStream(file);          ObjectOutputStream oos = new ObjectOutputStream(fos);          oos.writeObject(p);          FileInputStream fis = new FileInputStream(file);          ObjectInputStream ois = new ObjectInputStream(fis);          Point pp = (Point) ois.readObject();          System.out.println(pp);      }  }   transient关键字 关闭序列化自动进行。不管你选择了哪种序列化形式,都要为自己编写的每个可序列化的类声明一个显示的序列版本UID(serial version UID)

三、序列化的问题

在effective Java中列举出了java序列化要注意的一些问题:

谨慎地设计实现Serializable接口实现发布了就是一种承诺如果一个类是为继承设计的,在‘允许子类实现Serializable接口’与‘禁止子类实现Serializable接口’取一个折中的方案是:提供一个可访问的无参构造器保护性地编写 readObject()方法,因为readObject()是构建实例的入口。不保护可能出现 构建了不满足要求的 实例考虑自定义的序列化形式逻辑内容 与 物理表示法如果一个对象的 ‘物理表示法’等同于它的‘逻辑内容’,可能就适用于使用默认的序列化形式。如果有更好的 ‘物理表示法’在表示‘逻辑内容’则可以自定义序列化形式。[java] view plain copypublic class StringList implements Serializable {      private transient int size = 0;      private transient Entity head = null;      public final void add(String str) {          // ...      }      private static class Entity {          String data;          Entity next;          Entity previous;      }      private void writeObject(ObjectOutputStream s) throws IOException {          s.defaultWriteObject();          s.write(size);          for (Entity e = head; e != null; e = e.next) {              s.writeObject(e.data);          }      }      private void readObject(ObjectInputStream s) throws IOException,              ClassNotFoundException {          s.defaultReadObject();          int num = s.read();          for (int i = 0; i < num; i++) {              this.add((String) s.readObject());          }      }  }   

四、序列化代理模式

    序列化机制提供的钩子函数有:

       writeReplace writeObject  readObject  readResolve

writeReplace:序列化的时候替换所要序列化的对象。writeObject:写入序列化的对象 readObject:读取序列化的对象readResolve:最后返回序列化对象[java] view plain copyimport java.io.InvalidObjectException;  import java.io.ObjectInputStream;  import java.io.Serializable;  import java.util.Date;  public final class Period implements Serializable {      private static final long serialVersionUID = 100L;      private final Date start;      private final Date end;      public Period(Date start, Date end) {          this.start = new Date(start.getTime());          this.end = new Date(end.getTime());          if (this.start.compareTo(this.end) > 0) {              throw new IllegalArgumentException(start + " after " + end);          }      }      public Date start() {          return new Date(start.getTime());      }      public Date end() {          return new Date(end.getTime());      }      public String toString() {          return start + " - " + end;      }      // 不给      private Object writeReplace() {          return new SerializationProxy(this);      }      private void readObject(ObjectInputStream stream)              throws InvalidObjectException {          throw new InvalidObjectException("proxy request");      }      private static class SerializationProxy implements Serializable {          private final Date start;          private final Date end;          SerializationProxy(Period p) {              this.start = p.start;              this.end = p.end;          }          private Object readResolve() {              return new Period(start, end);          }          private static final long serialVersionUID = 1000L;      }  }   

五、序列化算法

将对象实例相关的类元数据输出。递归地输出类的超类描述直到不再有超类。类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。从上至下递归输出实例的数据

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:523047986  我们一起学Java!


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表