/** * Underlying readObject implementation. */ private Object readObject0(boolean unshared)throws IOException { boolean oldMode = bin.getBlockDataMode(); if (oldMode) { int remain = bin.currentBlockRemaining(); if (remain > 0) { thrownew OptionalDataException(remain); } elseif (defaultDataEnd) { /* * 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. */ thrownew OptionalDataException(true); } bin.setBlockDataMode(false); }
case TC_REFERENCE: // handle 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: // Object return checkResolve(readOrdinaryObject(unshared));
case TC_EXCEPTION: IOException ex = readFatalException(); thrownew WriteAbortedException("writing aborted", ex);
case TC_BLOCKDATA: case TC_BLOCKDATALONG: if (oldMode) { bin.setBlockDataMode(true); bin.peek(); // force header read thrownew OptionalDataException( bin.currentBlockRemaining()); } else { thrownew StreamCorruptedException( "unexpected block data"); }
case TC_ENDBLOCKDATA: if (oldMode) { thrownew OptionalDataException(true); } else { thrownew StreamCorruptedException( "unexpected end of block data"); }
/** * Reads and returns "ordinary" (i.e., not a String, Class, * ObjectStreamClass, array, or enum constant) object, or null if object's * class is unresolvable (in which case a ClassNotFoundException will be * associated with object's handle). Sets passHandle to object's assigned * handle. */ private Object readOrdinaryObject(boolean unshared) throws IOException { //首先再次确认TC_OBJECT,不是的话直接报错 if (bin.readByte() != TC_OBJECT) { thrownew InternalError(); } //读取当前类的类描述符号 ObjectStreamClass desc = readClassDesc(false); //检查是否可以反序列化 desc.checkDeserialize();
Class<?> cl = desc.forClass(); if (cl == String.class || cl== Class.class || cl== ObjectStreamClass.class) { thrownew InvalidClassException("invalid class descriptor"); }
/** * Reads in and returns class descriptor for a class that is not a dynamic * proxy class. Sets passHandle to class descriptor's assigned handle. If * class descriptor cannot be resolved to a class in the local VM, a * ClassNotFoundException is associated with the descriptor's handle. */ private ObjectStreamClass readNonProxyDesc(boolean unshared) throws IOException { if (bin.readByte() != TC_CLASSDESC) { thrownew InternalError(); }
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); }
/** * Skips over all block data and objects until TC_ENDBLOCKDATA is * encountered. */ privatevoidskipCustomData()throws IOException { int oldHandle = passHandle; for (;;) { if (bin.getBlockDataMode()) { bin.skipBlockData(); bin.setBlockDataMode(false); } switch (bin.peekByte()) { case TC_BLOCKDATA: case TC_BLOCKDATALONG: bin.setBlockDataMode(true); break;
case TC_ENDBLOCKDATA: bin.readByte(); passHandle = oldHandle; return;
privatevoidreadSerialData(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 (slots[i].hasData) { if (obj == null || handles.lookupException(passHandle) != null) { defaultReadFields(null, slotDesc); // skip field values } elseif (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); // 如果有readObject方法,执行 slotDesc.invokeReadObject(obj, this); } catch (ClassNotFoundException ex) { /* * In most cases, the handle table has already * propagated a CNFException to passHandle at this * point; this mark call is included to address cases * where the custom readObject method has cons'ed and * thrown a new CNFException of its own. */ handles.markException(passHandle, ex); } finally { do { try { curContext.setUsed(); if (oldContext!= null) oldContext.check(); curContext = oldContext; reset = true; } catch (ThreadDeath x) { t = x; // defer until reset is true } } while (!reset); if (t != null) throw t; }
/* * defaultDataEnd may have been set indirectly by custom * readObject() method when calling defaultReadObject() or * readFields(); clear it to restore normal read behavior. */ defaultDataEnd = false; } else { // 如果没有的话就执行默认的反序列化,给字段赋值 defaultReadFields(obj, slotDesc); }