< prev index next >

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

Print this page

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


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





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

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

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






2276             readExternalData((Externalizable) obj, desc);










2277         } else {



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

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

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