简介
由于反序列化时会重新生成一个新的对象实例,这与单例模式和枚举类实现唯一性原则相违背,为了使它们不矛盾,必须修改反 序列化的流程来实现唯一性
实现
在目标类中增加下列方法:
private Object readResolve();
1)单例模式
StudentSingleton.java
package com.siyuan.serializable;
import java.io.Serializable;
public class StudentSingleton implements Serializable{
private static final long serialVersionUID = -6060021285898900767L;
private int id;
private static final StudentSingleton instance = new StudentSingleton(1);
private StudentSingleton(int id) {
this.id = id;
}
public static StudentSingleton getInstance() {
return instance;
}
private Object readResolve() {
System.out.println("readResolve ... ");
return instance;
}
}
StudentSingletonTest.java
package com.siyuan.serializable.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.siyuan.serializable.StudentSingleton;
public class StudentSingletonTest {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
StudentSingleton stu = StudentSingleton.getInstance();
System.out.println(stu);
System.out.println("Serialized begin...");
ByteArrayOutputStream output = new ByteArrayOutputStream();
ObjectOutputStream objOutput = new ObjectOutputStream(output);
objOutput.writeObject(stu);
System.out.println("Serialized end...");
System.out.println("Deserialized begin...");
ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
ObjectInputStream objInput = new ObjectInputStream(input);
StudentSingleton stuDe = (StudentSingleton) objInput.readObject();
System.out.println("Deserialized end...");
System.out.println(stuDe);
}
}
运行结果
com.siyuan.serializable.StudentSingleton@757aef
Serialized begin...
Serialized end...
Deserialized begin...
readResolve ...
Deserialized end...
com.siyuan.serializable.StudentSingleton@757aef
2)枚举类实现
ColorEnum.java
package com.siyuan.serializable;
import java.io.Serializable;
public class ColorEnum implements Serializable{
private static final long serialVersionUID = 3995474245155583240L;
public static final ColorEnum RED = new ColorEnum("red");
public static final ColorEnum GREEN = new ColorEnum("green");
public static final ColorEnum BLUE = new ColorEnum("blue");
private String color;
private ColorEnum(String color) {
this.color = color;
}
private Object readResolve() {
System.out.println("readResolve ... ");
if ("red".equals(this.color)) {
return RED;
} else if ("green".equals(this.color)) {
return GREEN;
} else if ("blue".equals(this.color)) {
return BLUE;
} else {
throw new IllegalStateException();
}
}
}
ColorEnumTest.java
package com.siyuan.serializable.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.siyuan.serializable.ColorEnum;
public class ColorEnumTest {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
ColorEnum red = ColorEnum.RED;
System.out.println(red);
System.out.println("Serialized begin...");
ByteArrayOutputStream output = new ByteArrayOutputStream();
ObjectOutputStream objOutput = new ObjectOutputStream(output);
objOutput.writeObject(red);
System.out.println("Serialized end...");
System.out.println("Deserialized begin...");
ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
ObjectInputStream objInput = new ObjectInputStream(input);
ColorEnum redDe = (ColorEnum) objInput.readObject();
System.out.println("Deserialized end...");
System.out.println(redDe);
}
}
运行结果
com.siyuan.serializable.ColorEnum@757aef
Serialized begin...
Serialized end...
Deserialized begin...
readResolve ...
Deserialized end...
com.siyuan.serializable.ColorEnum@757aef
参考资料
http://www.javapractices.com/home/HomeAction.do