参考: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 对象
*/