Java-ObjectInputStream 反序列化 源码解析
ObjectInputStream
构造方法:
//需要传入一个 输入流,因为反序列化的来源的是一个 输入流
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();//验证 此类是不是 ObjectInputStream
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader(); //验证魔数和版本号
bin.setBlockDataMode(true); //blkMode = true pos = 0 end = 0
}
方法:
//验证序列化header
protected void readStreamHeader()
throws IOException, StreamCorruptedException
{
short s0 = bin.readShort();//魔数 pos = 2
short s1 = bin.readShort();//版本号 pos = 4
if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
throw new StreamCorruptedException(
String.format("invalid stream header: %04X%04X", s0, s1));
}
}
//反序列化方法的入口
public final Object readObject()
throws IOException, ClassNotFoundException
{
if (enableOverride) {
return readObjectOverride();
}
// if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle;
try {//方法转移
Object obj = readObject0(false);
handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) {
throw ex;
}
if (depth == 0) {
vlist.doCallbacks();
}
return obj;
} finally {
passHandle = outerHandle;
if (closed && depth == 0) {
clear();
}
}
}
//真正开始反序列化的方法
private Object readObject0(boolean unshared) throws IOException {
boolean oldMode = bin.getBlockDataMode(); //oldBlkMode is true
if (oldMode) {//判断
int remain = bin.currentBlockRemaining(); //返回 0
if (remain > 0) {
throw new OptionalDataException(remain);
} else if (defaultDataEnd) { //false
/*
* Fix for 4360508: stream is currently at the end of a field
* value block written via default serialization; since there
* is no terminating TC_ENDBLOCKDATA tag, simulate
* end-of-custom-data behavior explicitly.
*/
throw new OptionalDataException(true);
}
bin.setBlockDataMode(false); //blkMode is false
}
byte tc;
while ((tc = bin.peekByte()) == TC_RESET) {//peek 一下下一个 byte,直到不是TC_RESET
bin.readByte();
handleReset();
}
depth++;
totalObjectRefs++;
try {
switch (tc) {
case TC_NULL:
return readNull();
case TC_REFERENCE:
return readHandle(unshared);
case TC_CLASS:
return readClass(unshared);
case TC_CLASSDESC:
case TC_PROXYCLASSDESC:
return readClassDesc(unshared);
case TC_STRING:
case TC_LONGSTRING:
return checkResolve(readString(unshared));
case TC_ARRAY:
return checkResolve(readArray(unshared));
case TC_ENUM:
return checkResolve(readEnum(unshared));
case TC_OBJECT: //如果是序列化的对象,则会是这个分支
//checkResolve 的没有什么大用处 主要在 用户继承ObjectInputStream实现自己的 业务
return checkResolve(readOrdinaryObject(unshared));
case TC_EXCEPTION:
IOException ex = readFatalException();
throw new WriteAbortedException("writing aborted", ex);
case TC_BLOCKDATA:
case TC_BLOCKDATALONG:
if (oldMode) {
bin.setBlockDataMode(true);
bin.peek(); // force header read
throw new OptionalDataException(
bin.currentBlockRemaining());
} else {
throw new StreamCorruptedException(
"unexpected block data");
}
case TC_ENDBLOCKDATA:
if (oldMode) {
throw new OptionalDataException(true);
} else {
throw new StreamCorruptedException(
"unexpected end of block data");
}
default:
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
} finally {
depth--;
bin.setBlockDataMode(oldMode);
}
}
//反序列化 object
private Object readOrdinaryObject(boolean unshared)
throws IOException
{
if (bin.readByte() != TC_OBJECT) {//读取一个 byte,判断是否为 object 类型
throw new InternalError();
}
ObjectStreamClass desc = readClassDesc(false);//读取 classDesc
desc.checkDeserialize();
Class<?> cl = desc.forClass();//获取拿到的 需要反序列化 的类的class对象
if (cl == String.class || cl == Class.class
|| cl == ObjectStreamClass.class) {
throw new InvalidClassException("invalid class descriptor");
}
Object obj;
try {//反射产生对象
obj = desc.isInstantiable() ? desc.newInstance() : null;
} catch (Exception ex) {
throw (IOException) new InvalidClassException(
desc.forClass().getName(),
"unable to create instance").initCause(ex);
}
passHandle = handles.assign(unshared ? unsharedMarker : obj);
ClassNotFoundException resolveEx = desc.getResolveException();
if (resolveEx != null) {
handles.markException(passHandle, resolveEx);
}
if (desc.isExternalizable()) {
readExternalData((Externalizable) obj, desc);
} else {//给对象赋值
readSerialData(obj, desc);
}
handles.finish(passHandle);
if (obj != null &&
handles.lookupException(passHandle) == null &&
desc.hasReadResolveMethod())
{
Object rep = desc.invokeReadResolve(obj);
if (unshared && rep.getClass().isArray()) {
rep = cloneArray(rep);
}
if (rep != obj) {
// Filter the replacement object
if (rep != null) {
if (rep.getClass().isArray()) {
filterCheck(rep.getClass(), Array.getLength(rep));
} else {
filterCheck(rep.getClass(), -1);
}
}
handles.setObject(passHandle, obj = rep);
}
}
return obj;
}
//读取输入流中的 classDesc
private ObjectStreamClass readClassDesc(boolean unshared)
throws IOException
{
byte tc = bin.peekByte(); //peek 一个 byte
ObjectStreamClass descriptor;
switch (tc) {
case TC_NULL:
descriptor = (ObjectStreamClass) readNull();
break;
case TC_REFERENCE:
descriptor = (ObjectStreamClass) readHandle(unshared);
break;
case TC_PROXYCLASSDESC:
descriptor = readProxyDesc(unshared);
break;
case TC_CLASSDESC: //class 序列化 走这个分支
descriptor = readNonProxyDesc(unshared);//真正处理的方法
break;
default:
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
if (descriptor != null) {
validateDescriptor(descriptor);
}
return descriptor;
}
//没有代理的对象Desc read 方法
private ObjectStreamClass readNonProxyDesc(boolean unshared)
throws IOException
{
if (bin.readByte() != TC_CLASSDESC) {//获取这个 byte
throw new InternalError();
}
//new 一个 ObjectStreamClass
ObjectStreamClass desc = new ObjectStreamClass();
int descHandle = handles.assign(unshared ? unsharedMarker : desc);
passHandle = NULL_HANDLE;
ObjectStreamClass readDesc = null;
try {
readDesc = readClassDescriptor();//调用这个方法 获取 类描述对象
} catch (ClassNotFoundException ex) {
throw (IOException) new InvalidClassException(
"failed to read class descriptor").initCause(ex);
}
Class<?> cl = null;
ClassNotFoundException resolveEx = null;
bin.setBlockDataMode(true);
final boolean checksRequired = isCustomSubclass();
try {
if ((cl = resolveClass(readDesc)) == null) {
resolveEx = new ClassNotFoundException("null class");
} else if (checksRequired) {
ReflectUtil.checkPackageAccess(cl);
}
} catch (ClassNotFoundException ex) {
resolveEx = ex;
}
// Call filterCheck on the class before reading anything else
filterCheck(cl, -1);
skipCustomData();
try {
totalObjectRefs++;
depth++;
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));//init 目标的 desc
} finally {
depth--;
}
handles.finish(descHandle);
passHandle = descHandle;
return desc;
}
BlockDataInputStream
这个类是辅助读取 输入流的内容
方法:
//当模式 由false 变为true的时候,会pos=0,end=0
boolean setBlockDataMode(boolean newmode) throws IOException {
if (blkmode == newmode) {
return blkmode;
}
if (newmode) {
pos = 0;
end = 0;
unread = 0;
} else if (pos < end) {
throw new IllegalStateException("unread block data");
}
blkmode = newmode;
return !blkmode;
}