自定义序列化的应用
场景1. 序列化时不包含某个字段,如密码,但反序列化时却需要该字段。此时不能使用transient修饰字段,因其序列化/反序列化时都会排除其修饰的属性。
场景2. 其他特殊场景
使用方式
自定义序列化的类需要实现接口:java.io.Serializable,并重写以下方法:
- private void writeObject(ObjectOutputStream out)
//序列化时调用此方法
- private void readObject(ObjectInputStream in)
//反序列化时调用此方法
- private void readObjectNoData()
//当序列化的类版本和反序列化的类版本不同或者ObjectInputStream流被修改时,会调用此方法。
- private Object writeReplace()
//该方法返回的对象作为序列化的实际对象(因此可以在此更新序列化的对象)。
Demo(A对象序列化为B对象,反序列化B对象)
- 序列化的源对象
public class SourceObj implements Serializable {
private String name;
private Integer age;
public SourceObj(String name, int age) {
this.name = name;
this.age = age;
}
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
objectInputStream.defaultReadObject();
System.out.println("readObject");
}
private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
objectOutputStream.defaultWriteObject();
System.out.println("writeObject");
}
/**
* 在此处进行序列化对象的转换
* @return
*/
private Object writeReplace() {
System.out.println("执行方法:writeReplace,将SourceObj对象序列化的时候转为DesObj对象");
// return new SourceObj("老艾", 122);
return new DesObj(this.name + "今年" + this.age + "岁");
}
@Override
public String toString() {
return "SourceObj{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 序列化的目标对象
public class DesObj implements Serializable {
private String msg;
public DesObj(String msg) {
this.msg = msg;
}
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
objectInputStream.defaultReadObject();
System.out.println("DesObj.readObject");
}
private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
objectOutputStream.defaultWriteObject();
System.out.println("DesObj.writeObject");
}
@Override
public String toString() {
return "DesObj{" +
"msg='" + msg + '\'' +
'}';
}
}
- 测试
public class SerializableTest {
/**
* 将对象SourceObj序列化的过程改为另一个对象
* @throws IOException
*/
@Test
public void testOut() throws IOException {
SourceObj sourceObj = new SourceObj("老李", 99);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.buf"));
objectOutputStream.writeObject(sourceObj);
objectOutputStream.flush();
objectOutputStream.close();
}
/**
* 反序列化DesObj
* @throws IOException
* @throws ClassNotFoundException
*/
@Test
public void testIn() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.buf"));
DesObj desObj = (DesObj) objectInputStream.readObject();
System.out.println(desObj);
}
}
- 序列化输出
在执行writeObject()方法前会先执行writeReplace()方法
执行方法:writeReplace,将SourceObj对象序列化的时候转为DesObj对象
DesObj.writeObject
- 反序列化输出(DesObj反序列化出的内容)
DesObj.readObject
DesObj{msg='老李今年99岁'}