java序列化

一、序列化

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

二、Java序列化

  • 一个对象能够序列化的前提是实现Serializable接口。Serializable接口没有方法,更像是个标记。有了这个标记的Class就能被序列化机制处理。如下:
  • class myPoint implements Serializable{ }  
  • JAVA反序列化不会调用任何构造器
  • 序列化的控制:Externalizable。读写都交给你
    • 要在方法writeExternal写入序列化的参数
    • 要在方法readExternal读取反序列化的值
    • 要有默认的构造方法(readExternal执行完成,再执行默认的构造器)
    • void 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序列化要注意的一些问题:

  1. 谨慎地设计实现Serializable接口
    • 实现发布了就是一种承诺
    • 如果一个类是为继承设计的,在‘允许子类实现Serializable接口’与‘禁止子类实现Serializable接口’取一个折中的方案是:提供一个可访问的无参构造器
  2. 保护性地编写 readObject()方法,因为readObject()是构建实例的入口。
    • 不保护可能出现 构建了不满足要求的 实例
  3. 考虑自定义的序列化形式
    • 逻辑内容 与 物理表示法
    • 如果一个对象的 ‘物理表示法’等同于它的‘逻辑内容’,可能就适用于使用默认的序列化形式。
    • 如果有更好的 ‘物理表示法’在表示‘逻辑内容’则可以自定义序列化形式。
    • public 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:最后返回序列化对象
  • import 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; } }

五、序列化算法

  1. 将对象实例相关的类元数据输出。
  2. 递归地输出类的超类描述直到不再有超类。
  3. 类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
  4. 从上至下递归输出实例的数据
  • 具体参考,讲得很详细的:http://longdick.javaeye.com/blog/458557

六、参考文献

  • javatips's blog,The Java serialization algorithm revealed: http://www.javaworld.com/community/node/2915 
  • Blog ,Java 序列化算法透析:http://longdick.javaeye.com/blog/458557
  • Java Object Serialization Specification:http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf
  • java编程思想 http://www.bookfm.com/reader/online.html?bookid=123482&page=1

 

你可能感兴趣的:(java,Date,String,object,serialization,Class)