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);
|