一、writeObject
public final void writeObject(Object obj) throws IOException {
if (this.enableOverride) {
this.writeObjectOverride(obj);
} else {
try {
this.writeObject0(obj, false);
} catch (IOException var3) {
if (this.depth == 0) {
this.writeFatalException(var3);
}
throw var3;
}
}
}
enableOverride通过调用不同的构造赋值,一般为false,调用writeObject0方法
二、writeObject0
private void writeObject0(Object obj, boolean unshared) throws IOException {
boolean oldMode = this.bout.setBlockDataMode(false);
++this.depth;
try {
//使用subs.lookup查找对象obj,调用ReplaceTable的lookup
if ((obj = this.subs.lookup(obj)) == null) {
this.writeNull();
return;
}
int h;
//如果在数组中可以找到 调用writeHandle
if (!unshared && (h = this.handles.lookup(obj)) != -1) {
this.writeHandle(h);
return;
}
//如果是Class对象
if (!(obj instanceof Class)) {
//ObjectStreamClass 类用于描述序列化对象的类的信息
//如果是ObjectStreamClass对象
if (obj instanceof ObjectStreamClass) {
this.writeClassDesc((ObjectStreamClass)obj, unshared);
return;
}
Object orig = obj;
Class<?> cl = obj.getClass();
while(true) {
ObjectStreamClass desc = ObjectStreamClass.lookup(cl, true);
Class repCl;
//是否有writeReplace方法 反射调用writeReplace
if (!desc.hasWriteReplaceMethod() || (obj = desc.invokeWriteReplace(obj)) == null || (repCl = obj.getClass()) == cl) {
if (this.enableReplace) {
Object rep = this.replaceObject(obj);
if (rep != obj && rep != null) {
cl = rep.getClass();
//获取对象描述信息
desc = ObjectStreamClass.lookup(cl, true);
}
obj = rep;
}
if (obj != orig) {
//将替换对象存储到数组
this.subs.assign(orig, obj);
if (obj == null) {
this.writeNull();
return;
}
if (!unshared && (h = this.handles.lookup(obj)) != -1) {
this.writeHandle(h);
return;
}
if (obj instanceof Class) {
this.writeClass((Class)obj, unshared);
return;
}
if (obj instanceof ObjectStreamClass) {
this.writeClassDesc((ObjectStreamClass)obj, unshared);
return;
}
}
//如果是String对象
if (obj instanceof String) {
this.writeString((String)obj, unshared);
return;
}
//如果是数组
else if (cl.isArray()) {
this.writeArray(obj, desc, unshared);
return;
} else {//如果是枚举
if (obj instanceof Enum) {
this.writeEnum((Enum)obj, desc, unshared);
} else {
if (!(obj instanceof Serializable)) {
if (extendedDebugInfo) {
throw new NotSerializableException(cl.getName() + "\n" + this.debugInfoStack.toString());
}
throw new NotSerializableException(cl.getName());
}
//将普通对象写入输出流
this.writeOrdinaryObject(obj, desc, unshared);
}
return;
}
}
cl = repCl;
}
}
//将类信息写入输出流
this.writeClass((Class)obj, unshared);
} finally {
--this.depth;
this.bout.setBlockDataMode(oldMode);
}
}
private static class ReplaceTable {
Object lookup(Object obj) {
//在一个数组中查找有没有这个对象,返回下标,下标为-1就是没找到,返回obj
int index = this.htab.lookup(obj);
return index >= 0 ? this.reps[index] : obj;
}
}
private static class HandleTable {
int lookup(Object obj) {
if (this.size == 0) {
return -1;
} else {
int index = this.hash(obj) % this.spine.length;
for(int i = this.spine[index]; i >= 0; i = this.next[i]) {
if (this.objs[i] == obj) {
return i;
}
}
return -1;
}
}
}
三、writeOrdinaryObject
private void writeOrdinaryObject(Object obj, ObjectStreamClass desc, boolean unshared) throws IOException {
if (extendedDebugInfo) {
this.debugInfoStack.push((this.depth == 1 ? "root " : "") + "object (class \"" + obj.getClass().getName() + "\", " + obj.toString() + ")");
}
try {
desc.checkSerialize();
this.bout.writeByte(115);
this.writeClassDesc(desc, false);
this.handles.assign(unshared ? null : obj);
if (desc.isRecord()) {
this.writeRecordData(obj, desc);
} else if (desc.isExternalizable() && !desc.isProxy()) {
//如果实现Externalizable接口
this.writeExternalData((Externalizable)obj);
} else {
//如果实现Serializable接口
this.writeSerialData(obj, desc);
}
} finally {
if (extendedDebugInfo) {
this.debugInfoStack.pop();
}
}
}
四、writeSerialData
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;
//目标类是否有writeObject方法
if (slotDesc.hasWriteObjectMethod()) {
PutFieldImpl oldPut = this.curPut;
this.curPut = null;
SerialCallbackContext oldContext = this.curContext;
if (extendedDebugInfo) {
this.debugInfoStack.push("custom writeObject data (class \"" + slotDesc.getName() + "\")");
}
try {
this.curContext = new SerialCallbackContext(obj, slotDesc);
this.bout.setBlockDataMode(true);
//调用目标类的writeObject
slotDesc.invokeWriteObject(obj, this);
this.bout.setBlockDataMode(false);
this.bout.writeByte(120);
} finally {
this.curContext.setUsed();
this.curContext = oldContext;
if (extendedDebugInfo) {
this.debugInfoStack.pop();
}
}
this.curPut = oldPut;
} else {
//目标类没有实现writeObject,调用此方法
this.defaultWriteFields(obj, slotDesc);
}
}
}
五、defaultWriteFields
//将对象的字段写入输出流
private void defaultWriteFields(Object obj, ObjectStreamClass desc) throws IOException {
Class<?> cl = desc.forClass();
if (cl != null && obj != null && !cl.isInstance(obj)) {
throw new ClassCastException();
} else {
desc.checkDefaultSerialize();
int primDataSize = desc.getPrimDataSize();
if (primDataSize > 0) {
if (this.primVals == null || this.primVals.length < primDataSize) {
this.primVals = new byte[primDataSize];
}
//写入基本数据类型
desc.getPrimFieldValues(obj, this.primVals);
this.bout.write(this.primVals, 0, primDataSize, false);
}
int numObjFields = desc.getNumObjFields();
if (numObjFields > 0) {
ObjectStreamField[] fields = desc.getFields(false);
Object[] objVals = new Object[numObjFields];
int numPrimFields = fields.length - objVals.length;
desc.getObjFieldValues(obj, objVals);
for(int i = 0; i < objVals.length; ++i) {
if (extendedDebugInfo) {
this.debugInfoStack.push("field (class \"" + desc.getName() + "\", name: \"" + fields[numPrimFields + i].getName() + "\", type: \"" + fields[numPrimFields + i].getType() + "\")");
}
try {
//递归调用了writeObject0
this.writeObject0(objVals[i], fields[numPrimFields + i].isUnshared());
} finally {
if (extendedDebugInfo) {
this.debugInfoStack.pop();
}
}
}
}
}
}
六、writeExternalData
private void writeExternalData(Externalizable obj) throws IOException {
PutFieldImpl oldPut = this.curPut;
this.curPut = null;
if (extendedDebugInfo) {
this.debugInfoStack.push("writeExternal data");
}
SerialCallbackContext oldContext = this.curContext;
try {
this.curContext = null;
if (this.protocol == 1) {
//执行序列化对象的writeExternal
obj.writeExternal(this);
} else {
this.bout.setBlockDataMode(true);
obj.writeExternal(this);
this.bout.setBlockDataMode(false);
this.bout.writeByte(120);
}
} finally {
this.curContext = oldContext;
if (extendedDebugInfo) {
this.debugInfoStack.pop();
}
}
this.curPut = oldPut;
}