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