< prev index next >

src/java.base/share/classes/java/io/ObjectInputStream.java

Print this page

 199  * <p>Serialization does not read or assign values to the fields of any object
 200  * that does not implement the java.io.Serializable interface.  Subclasses of
 201  * Objects that are not serializable can be serializable. In this case the
 202  * non-serializable class must have a no-arg constructor to allow its fields to
 203  * be initialized.  In this case it is the responsibility of the subclass to
 204  * save and restore the state of the non-serializable class. It is frequently
 205  * the case that the fields of that class are accessible (public, package, or
 206  * protected) or that there are get and set methods that can be used to restore
 207  * the state.
 208  *
 209  * <p>Any exception that occurs while deserializing an object will be caught by
 210  * the ObjectInputStream and abort the reading process.
 211  *
 212  * <p>Implementing the Externalizable interface allows the object to assume
 213  * complete control over the contents and format of the object's serialized
 214  * form.  The methods of the Externalizable interface, writeExternal and
 215  * readExternal, are called to save and restore the objects state.  When
 216  * implemented by a class they can write and read their own state using all of
 217  * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
 218  * the objects to handle any versioning that occurs.


 219  *
 220  * <p>Enum constants are deserialized differently than ordinary serializable or
 221  * externalizable objects.  The serialized form of an enum constant consists
 222  * solely of its name; field values of the constant are not transmitted.  To
 223  * deserialize an enum constant, ObjectInputStream reads the constant name from
 224  * the stream; the deserialized constant is then obtained by calling the static
 225  * method {@code Enum.valueOf(Class, String)} with the enum constant's
 226  * base type and the received constant name as arguments.  Like other
 227  * serializable or externalizable objects, enum constants can function as the
 228  * targets of back references appearing subsequently in the serialization
 229  * stream.  The process by which enum constants are deserialized cannot be
 230  * customized: any class-specific readObject, readObjectNoData, and readResolve
 231  * methods defined by enum types are ignored during deserialization.
 232  * Similarly, any serialPersistentFields or serialVersionUID field declarations
 233  * are also ignored--all enum types have a fixed serialVersionUID of 0L.
 234  *
 235  * <a id="record-serialization"></a>
 236  * <p>Records are serialized differently than ordinary serializable or externalizable
 237  * objects. During deserialization the record's canonical constructor is invoked
 238  * to construct the record object. Certain serialization-related methods, such
 239  * as readObject and writeObject, are ignored for serializable records. See
 240  * <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-records">
 241  * <cite>Java Object Serialization Specification,</cite> Section 1.13,
 242  * "Serialization of Records"</a> for additional information.
 243  *





 244  * @author      Mike Warres
 245  * @author      Roger Riggs
 246  * @see java.io.DataInput
 247  * @see java.io.ObjectOutputStream
 248  * @see java.io.Serializable
 249  * @see <a href="{@docRoot}/../specs/serialization/input.html">
 250  *      <cite>Java Object Serialization Specification,</cite> Section 3, "Object Input Classes"</a>
 251  * @since   1.1
 252  */
 253 public class ObjectInputStream
 254     extends InputStream implements ObjectInput, ObjectStreamConstants
 255 {
 256     /** handle value representing null */
 257     private static final int NULL_HANDLE = -1;
 258 
 259     /** marker for unshared objects in internal handle table */
 260     private static final Object unsharedMarker = new Object();
 261 
 262     /**
 263      * immutable table mapping primitive type names to corresponding

2245             throw new InternalError();
2246         }
2247 
2248         ObjectStreamClass desc = readClassDesc(false);
2249         desc.checkDeserialize();
2250 
2251         Class<?> cl = desc.forClass();
2252         if (cl == String.class || cl == Class.class
2253                 || cl == ObjectStreamClass.class) {
2254             throw new InvalidClassException("invalid class descriptor");
2255         }
2256 
2257         Object obj;
2258         try {
2259             obj = desc.isInstantiable() ? desc.newInstance() : null;
2260         } catch (Exception ex) {
2261             throw new InvalidClassException(desc.forClass().getName(),
2262                                             "unable to create instance", ex);
2263         }
2264 
2265         passHandle = handles.assign(unshared ? unsharedMarker : obj);

2266         ClassNotFoundException resolveEx = desc.getResolveException();
2267         if (resolveEx != null) {
2268             handles.markException(passHandle, resolveEx);
2269         }
2270 
2271         final boolean isRecord = desc.isRecord();
2272         if (isRecord) {
2273             assert obj == null;
2274             obj = readRecord(desc);
2275             if (!unshared)
2276                 handles.setObject(passHandle, obj);
2277         } else if (desc.isExternalizable()) {






2278             readExternalData((Externalizable) obj, desc);







2279         } else {



2280             readSerialData(obj, desc);
2281         }
2282 
2283         handles.finish(passHandle);
2284 
2285         if (obj != null &&
2286             handles.lookupException(passHandle) == null &&
2287             desc.hasReadResolveMethod())
2288         {
2289             Object rep = desc.invokeReadResolve(obj);
2290             if (unshared && rep.getClass().isArray()) {
2291                 rep = cloneArray(rep);
2292             }
2293             if (rep != obj) {
2294                 // Filter the replacement object
2295                 if (rep != null) {
2296                     if (rep.getClass().isArray()) {
2297                         filterCheck(rep.getClass(), Array.getLength(rep));
2298                     } else {
2299                         filterCheck(rep.getClass(), -1);

 199  * <p>Serialization does not read or assign values to the fields of any object
 200  * that does not implement the java.io.Serializable interface.  Subclasses of
 201  * Objects that are not serializable can be serializable. In this case the
 202  * non-serializable class must have a no-arg constructor to allow its fields to
 203  * be initialized.  In this case it is the responsibility of the subclass to
 204  * save and restore the state of the non-serializable class. It is frequently
 205  * the case that the fields of that class are accessible (public, package, or
 206  * protected) or that there are get and set methods that can be used to restore
 207  * the state.
 208  *
 209  * <p>Any exception that occurs while deserializing an object will be caught by
 210  * the ObjectInputStream and abort the reading process.
 211  *
 212  * <p>Implementing the Externalizable interface allows the object to assume
 213  * complete control over the contents and format of the object's serialized
 214  * form.  The methods of the Externalizable interface, writeExternal and
 215  * readExternal, are called to save and restore the objects state.  When
 216  * implemented by a class they can write and read their own state using all of
 217  * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
 218  * the objects to handle any versioning that occurs.
 219  * Value objects cannot be `java.io.Externalizable` because value objects are
 220  * immutable and `Externalizable.readExternal` is unable to modify the fields of the value.
 221  *
 222  * <p>Enum constants are deserialized differently than ordinary serializable or
 223  * externalizable objects.  The serialized form of an enum constant consists
 224  * solely of its name; field values of the constant are not transmitted.  To
 225  * deserialize an enum constant, ObjectInputStream reads the constant name from
 226  * the stream; the deserialized constant is then obtained by calling the static
 227  * method {@code Enum.valueOf(Class, String)} with the enum constant's
 228  * base type and the received constant name as arguments.  Like other
 229  * serializable or externalizable objects, enum constants can function as the
 230  * targets of back references appearing subsequently in the serialization
 231  * stream.  The process by which enum constants are deserialized cannot be
 232  * customized: any class-specific readObject, readObjectNoData, and readResolve
 233  * methods defined by enum types are ignored during deserialization.
 234  * Similarly, any serialPersistentFields or serialVersionUID field declarations
 235  * are also ignored--all enum types have a fixed serialVersionUID of 0L.
 236  *
 237  * <a id="record-serialization"></a>
 238  * <p>Records are serialized differently than ordinary serializable or externalizable
 239  * objects. During deserialization the record's canonical constructor is invoked
 240  * to construct the record object. Certain serialization-related methods, such
 241  * as readObject and writeObject, are ignored for serializable records. See
 242  * <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-records">
 243  * <cite>Java Object Serialization Specification,</cite> Section 1.13,
 244  * "Serialization of Records"</a> for additional information.
 245  *
 246  * <p>Value objects are deserialized differently than ordinary serializable objects or records.
 247  * See <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-value-objects">
 248  * <cite>Java Object Serialization Specification,</cite> Section 1.14,
 249  * "Serialization of Value Objects"</a> for additional information.
 250  *
 251  * @author      Mike Warres
 252  * @author      Roger Riggs
 253  * @see java.io.DataInput
 254  * @see java.io.ObjectOutputStream
 255  * @see java.io.Serializable
 256  * @see <a href="{@docRoot}/../specs/serialization/input.html">
 257  *      <cite>Java Object Serialization Specification,</cite> Section 3, "Object Input Classes"</a>
 258  * @since   1.1
 259  */
 260 public class ObjectInputStream
 261     extends InputStream implements ObjectInput, ObjectStreamConstants
 262 {
 263     /** handle value representing null */
 264     private static final int NULL_HANDLE = -1;
 265 
 266     /** marker for unshared objects in internal handle table */
 267     private static final Object unsharedMarker = new Object();
 268 
 269     /**
 270      * immutable table mapping primitive type names to corresponding

2252             throw new InternalError();
2253         }
2254 
2255         ObjectStreamClass desc = readClassDesc(false);
2256         desc.checkDeserialize();
2257 
2258         Class<?> cl = desc.forClass();
2259         if (cl == String.class || cl == Class.class
2260                 || cl == ObjectStreamClass.class) {
2261             throw new InvalidClassException("invalid class descriptor");
2262         }
2263 
2264         Object obj;
2265         try {
2266             obj = desc.isInstantiable() ? desc.newInstance() : null;
2267         } catch (Exception ex) {
2268             throw new InvalidClassException(desc.forClass().getName(),
2269                                             "unable to create instance", ex);
2270         }
2271 
2272         // Assign the handle and initially set to null or the unsharedMarker
2273         passHandle = handles.assign(unshared ? unsharedMarker : null);
2274         ClassNotFoundException resolveEx = desc.getResolveException();
2275         if (resolveEx != null) {
2276             handles.markException(passHandle, resolveEx);
2277         }
2278 
2279         final boolean isRecord = desc.isRecord();
2280         if (isRecord) {
2281             assert obj == null;
2282             obj = readRecord(desc);
2283             if (!unshared)
2284                 handles.setObject(passHandle, obj);
2285         } else if (desc.isExternalizable()) {
2286             if (desc.isValue()) {
2287                 throw new NotSerializableException("Externalizable not valid for value class "
2288                         + cl.getName());
2289             }
2290             if (!unshared)
2291                 handles.setObject(passHandle, obj);
2292             readExternalData((Externalizable) obj, desc);
2293         } else if (desc.isValue()) {
2294             // For value objects, read the fields and finish the buffer before publishing the ref
2295             assert obj != null : "obj == null: " + desc;
2296             readSerialData(obj, desc);
2297             obj = desc.finishValue(obj);
2298             if (!unshared)
2299                 handles.setObject(passHandle, obj);
2300         } else {
2301             // For all other objects, publish the ref and then read the data
2302             if (!unshared)
2303                 handles.setObject(passHandle, obj);
2304             readSerialData(obj, desc);
2305         }
2306 
2307         handles.finish(passHandle);
2308 
2309         if (obj != null &&
2310             handles.lookupException(passHandle) == null &&
2311             desc.hasReadResolveMethod())
2312         {
2313             Object rep = desc.invokeReadResolve(obj);
2314             if (unshared && rep.getClass().isArray()) {
2315                 rep = cloneArray(rep);
2316             }
2317             if (rep != obj) {
2318                 // Filter the replacement object
2319                 if (rep != null) {
2320                     if (rep.getClass().isArray()) {
2321                         filterCheck(rep.getClass(), Array.getLength(rep));
2322                     } else {
2323                         filterCheck(rep.getClass(), -1);
< prev index next >