序列化及其代理

来源:互联网 发布:mac apache php7配置 编辑:程序博客网 时间:2024/05/01 23:49

参考:http://www.infoq.com/cn/articles/cf-java-object-serialization-rmi


package elevenchapter;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.util.Calendar;import java.util.Date;/* * 78:使用序列化代理代替序列化实例类 */class Periods implements Serializable {    private static final long serialVersionUID = -1068352662434111297L;    private final Date start;    private final Date end;    public Periods(Date start, Date end) {this.start = new Date(start.getTime());this.end = new Date(end.getTime());if (start.compareTo(end) > 0)    throw new IllegalArgumentException(start + " after " + end);    }    public Date start() {return start;    }    public Date end() {return end;    }    /*     * 建立一个内部代理类,域和外围类的域都是一样的     */    private static class Proxy implements Serializable {private static final long serialVersionUID = -1068352662434111297L;private final Date start;private final Date end;public Proxy(Periods p) {    this.start = p.start;    this.end = p.end;}private void writeObject(ObjectOutputStream out) throws IOException {    out.defaultWriteObject();    System.out.println("proxy writeObject Method run");}private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {    in.defaultReadObject();    System.out.println("proxy readObject Method run");}// 只要将这个方法返回 periods 就可以了private Object readResolve() {    System.out.println("proxy readResolve Method run");    return new Periods(start,end);}    }    /*     * 序列化时会将此方法的返回值进行序列化,而不再是默认的序列     */    private Object writeReplace() {System.out.println("writeRepalce Method run");return new Proxy(this); // 序列化时将 proxy 进行序列化,要想对进进行反序列化进没有出错,就要在 proxy// 类中 将 readResolve方法重写,返回一个// periods,不然会出错,而外围类的其他序列化方法就不再执行,因为序列化进去的类为// proxy// 所以后面执行的序列化方法都是 proxy 里面的    }    private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();System.out.println("writeObject Method run");    }    private void readObject(ObjectInputStream in) throws IOException,    ClassNotFoundException {in.defaultReadObject();System.out.println("readObject Method run");    }    private Object readResolve() {System.out.println("readResolve Method run");return new Periods(start, end);    }    public String toString() {return String.format("start :%s,end: %s", start, end);    }}public class SevenEight {    public static void main(String args[]) throws FileNotFoundException,    IOException, ClassNotFoundException {long start = System.currentTimeMillis();long end = System.currentTimeMillis() + 5;Periods p = new Periods(new Date(start), new Date(end));writeObject(p);Periods pp = (Periods) readObject();System.out.println(pp.end().getTime()-pp.start().getTime());    }    public static void writeObject(Object o) throws FileNotFoundException,    IOException {ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("F:\\singleton.txt"));out.writeObject(o);out.close();System.out.println("对象成功写入...");    }    public static Object readObject() throws FileNotFoundException,    IOException, ClassNotFoundException {ObjectInputStream in = new ObjectInputStream(new FileInputStream("F:\\singleton.txt"));Object single = in.readObject();in.close();System.out.println("对象成功读取...");return single;    }}/* * Effective java 第78条:序列化的代理类: * 原是就是在要序列化的类中建立一个 private static class ,内部类与外围类拥有相同 的域, * 这样在外围类序列化的时候,利用  writeReplace 方法返回内部类的实例,将内部类序列化进去, * 这样在反序列化的过程中,就不会再调用外围类的 readObject readRolve 方法,而是调用 内部 * 类的这些方法,因为我们序列化进去的是内部类的实例,所以要重写 proxy 类中的 readResolve * 方法,让它在返回的值返回一个 priods 对象 */


原创粉丝点击