| CONTENTS | PREV | NEXT | Java Object Serialization Specification |
ClassObjectInputStreamimplements object deserialization. It maintains the state of the stream including the set of objects already deserialized. Its methods allow primitive types and objects to be read from a stream written byObjectOutputStream. It manages restoration of the object and the objects that it refers to from the stream.package java.io; public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants { public ObjectInputStream(InputStream in) throws StreamCorruptedException, IOException;public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException; public void defaultReadObject() throws IOException, ClassNotFoundException, NotActiveException; public GetField readFields() throws IOException; public synchronized void registerValidation( ObjectInputValidation obj, int prio) throws NotActiveException, InvalidObjectException; protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException; protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException; protected Object resolveObject(Object obj) throws IOException; protected boolean enableResolveObject(boolean enable) throws SecurityException; protected void readStreamHeader() throws IOException, StreamCorruptedException; public int read() throws IOException; public int read(byte[] data, int offset, int length) throws IOException public int available() throws IOException; public void close() throws IOException; public boolean readBoolean() throws IOException; public byte readByte() throws IOException; public int readUnsignedByte() throws IOException; public short readShort() throws IOException; public int readUnsignedShort() throws IOException; public char readChar() throws IOException; public int readInt() throws IOException; public long readLong() throws IOException; public float readFloat() throws IOException; public double readDouble() throws IOException; public void readFully(byte[] data) throws IOException; public void readFully(byte[] data, int offset, int size) throws IOException; public int skipBytes(int len) throws IOException; public String readLine() throws IOException; public String readUTF() throws IOException; // Class to provide access to serializable fields. static abstract public class GetField { public ObjectStreamClass getObjectStreamClass(); public boolean defaulted(String name) throws IOException, IllegalArgumentException; public char get(String name, char default) throws IOException, IllegalArgumentException; public boolean get(String name, boolean default) throws IOException, IllegalArgumentException; public byte get(String name, byte default) throws IOException, IllegalArgumentException; public short get(String name, short default) throws IOException, IllegalArgumentException; public int get(String name, int default) throws IOException, IllegalArgumentException; public long get(String name, long default) throws IOException, IllegalArgumentException; public float get(String name, float default) throws IOException, IllegalArgumentException; public double get(String name, double default) throws IOException, IllegalArgumentException; public Object get(String name, Object default) throws IOException, IllegalArgumentException; } protected ObjectInputStream() throws StreamCorruptedException, IOException; protected readObjectOverride() throws OptionalDataException, ClassNotFoundException, IOException; }TheObjectInputStreamconstructor requires anInputStream. The constructor callsreadStreamHeaderto read and verifies the header and version written by the correspondingObjectOutputStream.writeStreamHeadermethod.
Note - TheObjectInputStreamconstructor blocks until it completes reading the serialization stream header. Code which waits for anObjectInputStreamto be constructed before creating the correspondingObjectOutputStreamfor that stream will deadlock, since theObjectInputStreamconstructor will block until a header is written to the stream, and the header will not be written to the stream until theObjectOutputStreamconstructor executes. This problem can be resolved by creating theObjectOutputStreambefore theObjectInputStream, or otherwise removing the timing dependency between completion ofObjectInputStreamconstruction and the creation of theObjectOutputStream.
ThereadObjectmethod is used to deserialize an object from the stream. It reads from the stream to reconstruct an object.
ObjectInputStream subclass is overriding the implementation, call the readObjectOverride method and return. Reimplementation is described at the end of this section.
Class, read its ObjectStreamClass descriptor, add it and its handle to the set of known objects, and return the corresponding Class object.
ObjectStreamClass, read its name, serialVersionUID, and fields. Add it and its handle to the set of known objects. Call the resolveClass method on the stream to get the local class for this descriptor, and throw an exception if the class cannot be found. Return the ObjectStreamClass object.
ObjectStreamClass and the length of the array. Allocate the array, and add it and its handle in the set of known objects. Read each element using the appropriate method for its type and assign it to the array. Proceed to Step 11.
ObjectStreamClass of the object is read from the stream. The local class for that ObjectStreamClass is retrieved. The class must be serializable or externalizable.
readObject methods, or if these are not defined, by calling the defaultReadObject method. Note that field initializers and constructors are not executed for serializable classes during deserialization. In the normal case, the version of the class that wrote the stream will be the same as the class reading the stream. In this case, all of the supertypes of the object in the stream will match the supertypes in the currently-loaded class. If the version of the class that wrote the stream had different supertypes than the loaded class, the ObjectInputStream must be more careful about restoring or initializing the state of the differing classes. It must step through the classes, matching the available data in the stream with the classes of the object being restored. Data for classes that occur in the stream, but do not occur in the object, is discarded. For classes that occur in the object, but not in the stream, the class fields are set to default values by default serialization.
readExternal method is called to restore the contents of the object.
ObjectInputStream:
readResolve method, the method is called to allow the object to replace itself.
enableResolveObject, the resolveObject method is called to allow subclasses of the stream to examine and replace the object. If the previous step did replace the original object, the resolveObject method is called with the replacement object.
If a replacement took place, the table of known objects is updated so the replacement object is associated with the handle. The replacement object is then returned fromreadObject.All of the methods for reading primitives types only consume bytes from the block data records in the stream. If a read for primitive data occurs when the next item in the stream is an object, the read methods return -1 or the EOFException as appropriate. The value of a primitive type is read by a
DataInputStreamfrom the block data record.The exceptions thrown reflect errors during the traversal or exceptions that occur on the underlying stream. If any exception is thrown, the underlying stream is left in an unknown and unusable state.
When the reset token occurs in the stream, all of the state of the stream is discarded. The set of known objects is cleared.
When the exception token occurs in the stream, the exception is read and a new WriteAbortedException is thrown with the terminating exception as an argument. The stream context is reset as described earlier.
The
defaultReadObjectmethod is used to read the fields and object from the stream. It uses the class descriptor in the stream to read the fields in the canonical order by name and type from the stream. The values are assigned to the matching fields by name in the current class. Details of the versioning mechanism can be found in Section 5.5, "Compatible JavaTM Type Evolution." Any field of the object that does not appear in the stream is set to its default value. Values that appear in the stream, but not in the object, are discarded. This occurs primarily when a later version of a class has written additional fields that do not occur in the earlier version. This method may only be called from thereadObjectmethod while restoring the fields of a class. When called at any other time, the NotActiveException is thrown.The
readFieldsmethod reads the values of the serializable fields from the stream and makes them available via theGetFieldclass. ThereadFieldsmethod is only callable from within thereadObjectmethod of a serializable class. It cannot be called more than once or ifdefaultReadObjecthas been called. TheGetFieldsobject uses the current object'sObjectStreamClassto verify the fields that can be retrieved for this class. TheGetFieldsobject returned byreadFieldsis only valid during this call to the classesreadObjectmethod. The fields may be retrieved in any order. Additional data may only be read directly from stream afterreadFieldshas been called.The
registerValidationmethod can be called to request a callback when the entire graph has been restored but before the object is returned to the original caller ofreadObject. The order of validate callbacks can be controlled using the priority. Callbacks registered with higher values are called before those with lower values. The object to be validated must support theObjectInputValidationinterface and implement thevalidateObjectmethod. It is only correct to register validations during a call to a class'sreadObjectmethod. Otherwise, a NotActiveException is thrown. If the callback object supplied toregisterValidationis null, an InvalidObjectException is thrown.Starting with the JavaTM SDK, Standard Edition, v1.3, the
readClassDescriptormethod is used to read in allObjectStreamClassobjects.readClassDescriptoris called when theObjectInputStreamexpects a class descriptor as the next item in the serialization stream. Subclasses ofObjectInputStreammay override this method to read in class descriptors that have been written in non-standard formats (by subclasses ofObjectOutputStreamwhich have overridden thewriteClassDescriptormethod). By default, this method reads class descriptors according to the format described in Section 6.4, "Grammar for the Stream Format".The
resolveClassmethod is called while a class is being deserialized, and after the class descriptor has been read. Subclasses may extend this method to read other information about the class written by the corresponding subclass ofObjectOutputStream. The method must find and return the class with the given name andserialVersionUID. The default implementation locates the class by calling the class loader of the closest caller ofreadObjectthat has a class loader. If the class cannot be foundClassNotFoundExceptionshould be thrown. Prior to JDKTM 1.1.6, theresolveClassmethod was required to return the same fully qualified class name as the class name in the stream. In order to accommodate package renaming across releases,methodresolveClassonly needs to return a class with the same base class name andSerialVersionUIDin JDKTM 1.1.6 and later versions.The
resolveObjectmethod is used by trusted subclasses to monitor or substitute one object for another during deserialization. Resolving objects must be enabled explicitly by callingenableResolveObjectbefore callingreadObjectfor the first object to be resolved. Once enabled,resolveObjectis called once for each serializable object just prior to the first time it is being returned fromreadObject. Note that theresolveObjectmethod is not called for objects of the specially handled classes,Class,ObjectStreamClass,String, and arrays. A subclass's implementation ofresolveObjectmay return a substitute object that will be assigned or returned instead of the original. The object returned must be of a type that is consistent and assignable to every reference of the original object or else a ClassCastException will be thrown. All assignments are type-checked. All references in the stream to the original object will be replaced by references to the substitute object.The
enableResolveObjectmethod is called by trusted subclasses ofObjectOutputStreamto enable the monitoring or substitution of one object for another during deserialization. Replacing objects is disabled untilenableResolveObjectis called with a true value. It may thereafter be disabled by setting it to false. The previous setting is returned. TheenableResolveObjectmethod checks if the stream has permission to request substitution during serialization. To ensure that the private state of objects is not unintentionally exposed, only trusted streams may useresolveObject. Trusted classes are those classes with a class loader equal to null or belong to a security protection domain that provides permission to enable substitution.If the subclass of
ObjectInputStreamis not considered part of the system domain, a line has to be added to the security policy file to provide to a subclass ofObjectInputStreampermission to callenableResolveObject. TheSerializablePermissionto add is"enableSubstitution". AccessControlException is thrown if the protection domain of the subclass ofObjectStreamClassdoes not have permission to"enableSubstitution"by callingenableResolveObject. See the document JavaTM Security Architecture (JDKTM 1.2) for additional information about the security model.The
readStreamHeadermethod reads and verifies the magic number and version of the stream. If they do not match, the StreamCorruptedMismatch is thrown.To override the implementation of deserialization, a subclass of
ObjectInputStreamshould call the protected no-argObjectInputStream, constructor. There is a security check within the no-arg constructor forSerializablePermission "enableSubclassImplementation"to ensure that only trusted classes are allowed to override the default implementation. This constructor does not allocate any private data forObjectInputStreamand sets a flag that indicates that the finalreadObjectmethod should invoke thereadObjectOverridemethod and return. All otherObjectInputStreammethods are not final and can be directly overridden by the subclass.