java的序列化机制原理分析(一)

2014-11-24 08:12:20 · 作者: · 浏览: 11

我们查看下ObjectOutputStream的writeObject方法

[java]

//final方法,不允许子类覆盖
public final void writeObject(Object obj) throws IOException {
if (enableOverride) { //如果开启允许序列化被重写
writeObjectOverride(obj); //调用子类的序列化重写方法
return;
}
try {
writeObject0(obj, false);//调用默认的序列化过程
} catch (IOException ex) {
if (depth == 0) {
writeFatalException(ex);
}
throw ex;
}
}

如果要自定义这个序列化过程,则可以写一个子类,集成ObjectOutputStream,然后覆盖其两个方法
[java]
protected ObjectOutputStream() throws IOException, SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
bout = null;
handles = null;
subs = null;
enableOverride = true;
debugInfoStack = null;
}
protected void writeObjectOverride(Object obj) throws IOException {
}

我们再看下具体的writeObject0方法:
[java]
private void writeObject0(Object obj, boolean unshared)
throws IOException
{
boolean oldMode = bout.setBlockDataMode(false);
depth++;
try {
// 先对obj实例的类信息进行序列化,
int h;
if ((obj = subs.lookup(obj)) == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {//可以自定义class类信息的序列化handler
writeHandle(h);
return;
} else if (obj instanceof Class) { //类信息序列化
writeClass((Class) obj, unshared);
return;
} else if (obj instanceof ObjectStreamClass) { //类信息序列化,此时还包括serialVersionUID
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
}

// check for replacement object
//这里还可以对序列化的类进行替换序列化
Object orig = obj;
Class cl = obj.getClass();
ObjectStreamClass desc;
for (;;) {
// REMIND: skip this check for strings/arrays
Class repCl;
desc = ObjectStreamClass.lookup(cl, true);
if (!desc.hasWriteReplaceMethod() ||
(obj = desc.invokeWriteReplace(obj)) == null ||
(repCl = obj.getClass()) == cl)
{
break;
}
cl = repCl;
}
if (enableReplace) {
Object rep = replaceObject(obj);
if (rep != obj && rep != null) {
cl = rep.getClass();
desc = ObjectStreamClass.lookup(cl, true);
}
obj = rep;
}

// if object replaced, run through original checks a second time
//如果类信息被替换过,则需要进行第二次处理
if (obj != orig) {
subs.assign(orig, obj);
if (obj == null) {
writeNull();
return;
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);