在前两篇文章中分析了序列化与反序列化的流程,下面说一下Serializable中如果定义private void writeObject(ObjectOutputStrean os)和private void readObject(ObjectInputStrean os)的作用也就是在《对象序列化》那篇文章中分析的ObjectStreamClass中定义的两个成员变量writeObjectMethod和readObjectMethod。
在writeObject0方法中有一段代码
Class<?> repCl; desc = ObjectStreamClass.lookup(cl, true); if (!desc.hasWriteReplaceMethod() || (obj = desc.invokeWriteReplace(obj)) == null || (repCl = obj.getClass()) == cl) { break; } cl = repCl;
可以看到可以在对象中定义private Object writeReplace()方法用来替换原始的可序列化对象。
private void writeSerialData(Object obj, ObjectStreamClass desc) throws IOException { ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout(); for (int i = 0; i < slots.length; i++) { ObjectStreamClass slotDesc = slots[i].desc; if (slotDesc.hasWriteObjectMethod()) {//如果有writeObject()方法则用对象自定义的序列化方法 PutFieldImpl oldPut = curPut; curPut = null; SerialCallbackContext oldContext = curContext; if (extendedDebugInfo) { debugInfoStack.push( "custom writeObject data (class \"" + slotDesc.getName() + "\")"); } try { curContext = new SerialCallbackContext(obj, slotDesc); bout.setBlockDataMode(true); slotDesc.invokeWriteObject(obj, this);//在这执行 bout.setBlockDataMode(false); bout.writeByte(TC_ENDBLOCKDATA); } finally { curContext.setUsed(); curContext = oldContext; if (extendedDebugInfo) { debugInfoStack.pop(); } } curPut = oldPut; } else { defaultWriteFields(obj, slotDesc); } } }
如果定定义了writeObject()方法则会调用自定义的而不是默认的序列化方法defaultWriteFields(obj, slotDesc)。
同样在ObjectInputStream中readSerialData()方法中有如下代码
if (obj == null || handles.lookupException(passHandle) != null) { defaultReadFields(null, slotDesc); // skip field values } else if (slotDesc.hasReadObjectMethod()) { ThreadDeath t = null; boolean reset = false; SerialCallbackContext oldContext = curContext; if (oldContext != null) oldContext.check(); try { curContext = new SerialCallbackContext(obj, slotDesc); bin.setBlockDataMode(true); slotDesc.invokeReadObject(obj, this);
我们就知道了如果类中定义了writeObject和readObject方法就不会用默认的序列化和反序列化方法而是我们定义的这两个方法。
下面写个例子测试一下
public class Person extends Human implements Serializable {
public String xyz = "lmn";
public String name;
public int age = 55;
public int length = 66;
public int width = 77;
public static Person single=new Person("hero");
public Person(String name) {
super(name);
this.name = name;
}
private Object readResolve() {
return single;
}
private void writeObject(ObjectOutputStream os) throws IOException {
os.writeObject("自定义writeObject");
os.defaultWriteObject();
}
private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
System.out.println(is.readObject());
is.defaultReadObject();
}
}
测试用例
private static void testWriteObject() throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
Person p=Person.single;
oos.writeObject(p);
System.out.println(baos.toString());
ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bais);
Object readObject = ois.readObject();
System.out.println(readObject==p);
}
结果