44787
|
1 |
---
|
|
2 |
# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
#
|
|
5 |
# This code is free software; you can redistribute it and/or modify it
|
|
6 |
# under the terms of the GNU General Public License version 2 only, as
|
|
7 |
# published by the Free Software Foundation.
|
|
8 |
#
|
|
9 |
# This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 |
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 |
# version 2 for more details (a copy is included in the LICENSE file that
|
|
13 |
# accompanied this code).
|
|
14 |
#
|
|
15 |
# You should have received a copy of the GNU General Public License version
|
|
16 |
# 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 |
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 |
#
|
|
19 |
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
20 |
# or visit www.oracle.com if you need additional information or have any
|
|
21 |
# questions.
|
|
22 |
|
|
23 |
include-before: '[CONTENTS](index.html) | [PREV](output.html) | [NEXT](class.html)'
|
|
24 |
include-after: '[CONTENTS](index.html) | [PREV](output.html) | [NEXT](class.html)'
|
|
25 |
|
|
26 |
title: 'Java Object Serialization Specification: 3 - Object Input Classes'
|
|
27 |
---
|
|
28 |
|
|
29 |
- [The ObjectInputStream Class](#the-objectinputstream-class)
|
|
30 |
- [The ObjectInputStream.GetField
|
|
31 |
Class](#the-objectinputstream.getfield-class)
|
|
32 |
- [The ObjectInputValidation Interface](#the-objectinputvalidation-interface)
|
|
33 |
- [The readObject Method](#the-readobject-method)
|
|
34 |
- [The readExternal Method](#the-readexternal-method)
|
|
35 |
- [The readResolve Method](#the-readresolve-method)
|
|
36 |
|
|
37 |
-------------------------------------------------------------------------------
|
|
38 |
|
|
39 |
## 3.1 The ObjectInputStream Class
|
|
40 |
|
|
41 |
Class `ObjectInputStream` implements object deserialization. It maintains the
|
|
42 |
state of the stream including the set of objects already deserialized. Its
|
|
43 |
methods allow primitive types and objects to be read from a stream written by
|
|
44 |
`ObjectOutputStream`. It manages restoration of the object and the objects that
|
|
45 |
it refers to from the stream.
|
|
46 |
|
|
47 |
```
|
|
48 |
package java.io;
|
|
49 |
|
|
50 |
public class ObjectInputStream
|
|
51 |
extends InputStream
|
|
52 |
implements ObjectInput, ObjectStreamConstants
|
|
53 |
{
|
|
54 |
public ObjectInputStream(InputStream in)
|
|
55 |
throws StreamCorruptedException, IOException;
|
|
56 |
|
|
57 |
public final Object readObject()
|
|
58 |
throws OptionalDataException, ClassNotFoundException,
|
|
59 |
IOException;
|
|
60 |
|
|
61 |
public Object readUnshared()
|
|
62 |
throws OptionalDataException, ClassNotFoundException,
|
|
63 |
IOException;
|
|
64 |
|
|
65 |
public void defaultReadObject()
|
|
66 |
throws IOException, ClassNotFoundException,
|
|
67 |
NotActiveException;
|
|
68 |
|
|
69 |
public GetField readFields()
|
|
70 |
throws IOException;
|
|
71 |
|
|
72 |
public synchronized void registerValidation(
|
|
73 |
ObjectInputValidation obj, int prio)
|
|
74 |
throws NotActiveException, InvalidObjectException;
|
|
75 |
|
|
76 |
protected ObjectStreamClass readClassDescriptor()
|
|
77 |
throws IOException, ClassNotFoundException;
|
|
78 |
|
|
79 |
protected Class resolveClass(ObjectStreamClass v)
|
|
80 |
throws IOException, ClassNotFoundException;
|
|
81 |
|
|
82 |
protected Object resolveObject(Object obj)
|
|
83 |
throws IOException;
|
|
84 |
|
|
85 |
protected boolean enableResolveObject(boolean enable)
|
|
86 |
throws SecurityException;
|
|
87 |
|
|
88 |
protected void readStreamHeader()
|
|
89 |
throws IOException, StreamCorruptedException;
|
|
90 |
|
|
91 |
public int read() throws IOException;
|
|
92 |
|
|
93 |
public int read(byte[] data, int offset, int length)
|
|
94 |
throws IOException
|
|
95 |
|
|
96 |
public int available() throws IOException;
|
|
97 |
|
|
98 |
public void close() throws IOException;
|
|
99 |
|
|
100 |
public boolean readBoolean() throws IOException;
|
|
101 |
|
|
102 |
public byte readByte() throws IOException;
|
|
103 |
|
|
104 |
public int readUnsignedByte() throws IOException;
|
|
105 |
|
|
106 |
public short readShort() throws IOException;
|
|
107 |
|
|
108 |
public int readUnsignedShort() throws IOException;
|
|
109 |
|
|
110 |
public char readChar() throws IOException;
|
|
111 |
|
|
112 |
public int readInt() throws IOException;
|
|
113 |
|
|
114 |
public long readLong() throws IOException;
|
|
115 |
|
|
116 |
public float readFloat() throws IOException;
|
|
117 |
|
|
118 |
public double readDouble() throws IOException;
|
|
119 |
|
|
120 |
public void readFully(byte[] data) throws IOException;
|
|
121 |
|
|
122 |
public void readFully(byte[] data, int offset, int size)
|
|
123 |
throws IOException;
|
|
124 |
|
|
125 |
public int skipBytes(int len) throws IOException;
|
|
126 |
|
|
127 |
public String readLine() throws IOException;
|
|
128 |
|
|
129 |
public String readUTF() throws IOException;
|
|
130 |
|
|
131 |
// Class to provide access to serializable fields.
|
|
132 |
static abstract public class GetField
|
|
133 |
{
|
|
134 |
public ObjectStreamClass getObjectStreamClass();
|
|
135 |
|
|
136 |
public boolean defaulted(String name)
|
|
137 |
throws IOException, IllegalArgumentException;
|
|
138 |
|
|
139 |
public char get(String name, char default)
|
|
140 |
throws IOException, IllegalArgumentException;
|
|
141 |
|
|
142 |
public boolean get(String name, boolean default)
|
|
143 |
throws IOException, IllegalArgumentException;
|
|
144 |
|
|
145 |
public byte get(String name, byte default)
|
|
146 |
throws IOException, IllegalArgumentException;
|
|
147 |
|
|
148 |
public short get(String name, short default)
|
|
149 |
throws IOException, IllegalArgumentException;
|
|
150 |
|
|
151 |
public int get(String name, int default)
|
|
152 |
throws IOException, IllegalArgumentException;
|
|
153 |
|
|
154 |
public long get(String name, long default)
|
|
155 |
throws IOException, IllegalArgumentException;
|
|
156 |
|
|
157 |
public float get(String name, float default)
|
|
158 |
throws IOException, IllegalArgumentException;
|
|
159 |
|
|
160 |
public double get(String name, double default)
|
|
161 |
throws IOException, IllegalArgumentException;
|
|
162 |
|
|
163 |
public Object get(String name, Object default)
|
|
164 |
throws IOException, IllegalArgumentException;
|
|
165 |
}
|
|
166 |
|
|
167 |
protected ObjectInputStream()
|
|
168 |
throws StreamCorruptedException, IOException;
|
|
169 |
|
|
170 |
protected readObjectOverride()
|
|
171 |
throws OptionalDataException, ClassNotFoundException,
|
|
172 |
IOException;
|
|
173 |
}
|
|
174 |
```
|
|
175 |
|
|
176 |
The single-argument `ObjectInputStream` constructor requires an `InputStream`.
|
|
177 |
The constructor calls `readStreamHeader` to read and verifies the header and
|
|
178 |
version written by the corresponding `ObjectOutputStream.writeStreamHeader`
|
|
179 |
method. If a security manager is installed, this constructor checks for the
|
|
180 |
`"enableSubclassImplementation"` `SerializablePermission` when invoked directly
|
|
181 |
or indirectly by the constructor of a subclass which overrides the `readFields`
|
|
182 |
and/or `readUnshared` methods.
|
|
183 |
|
|
184 |
**Note:** The `ObjectInputStream` constructor blocks until it completes reading
|
|
185 |
the serialization stream header. Code which waits for an `ObjectInputStream` to
|
|
186 |
be constructed before creating the corresponding `ObjectOutputStream` for that
|
|
187 |
stream will deadlock, since the `ObjectInputStream` constructor will block
|
|
188 |
until a header is written to the stream, and the header will not be written to
|
|
189 |
the stream until the `ObjectOutputStream` constructor executes. This problem
|
|
190 |
can be resolved by creating the `ObjectOutputStream` before the
|
|
191 |
`ObjectInputStream`, or otherwise removing the timing dependency between
|
|
192 |
completion of `ObjectInputStream` construction and the creation of the
|
|
193 |
`ObjectOutputStream`.
|
|
194 |
|
|
195 |
The `readObject` method is used to deserialize an object from the stream. It
|
|
196 |
reads from the stream to reconstruct an object.
|
|
197 |
|
|
198 |
1. If the `ObjectInputStream` subclass is overriding the implementation, call
|
|
199 |
the `readObjectOverride` method and return. Reimplementation is described
|
|
200 |
at the end of this section.
|
|
201 |
|
|
202 |
2. If a block data record occurs in the stream, throw a `BlockDataException`
|
|
203 |
with the number of available bytes.
|
|
204 |
|
|
205 |
3. If the object in the stream is null, return null.
|
|
206 |
|
|
207 |
4. If the object in the stream is a handle to a previous object, return the
|
|
208 |
object.
|
|
209 |
|
|
210 |
5. If the object in the stream is a `Class`, read its `ObjectStreamClass`
|
|
211 |
descriptor, add it and its handle to the set of known objects, and return
|
|
212 |
the corresponding `Class` object.
|
|
213 |
|
|
214 |
6. If the object in the stream is an `ObjectStreamClass`, read in its data
|
|
215 |
according to the formats described in [Section 4.3, "Serialized
|
|
216 |
Form"](class.html#serialized-form). Add it and its handle to the set of
|
|
217 |
known objects. In versions 1.3 and later of the Java 2 SDK, Standard
|
|
218 |
Edition, the `readClassDescriptor` method is called to read in the
|
|
219 |
`ObjectStreamClass` if it represents a class that is not a dynamic proxy
|
|
220 |
class, as indicated in the stream data. If the class descriptor represents
|
|
221 |
a dynamic proxy class, call the `resolveProxyClass` method on the stream to
|
|
222 |
get the local class for the descriptor; otherwise, call the `resolveClass`
|
|
223 |
method on the stream to get the local class. If the class cannot be
|
|
224 |
resolved, throw a ClassNotFoundException. Return the resulting
|
|
225 |
`ObjectStreamClass` object.
|
|
226 |
|
|
227 |
7. If the object in the stream is a `String`, read its length information
|
|
228 |
followed by the contents of the string encoded in modified UTF-8. For
|
|
229 |
details, refer to [Section 6.2, "Stream
|
|
230 |
Elements"](protocol.html#stream-elements). Add the `String` and its handle
|
|
231 |
to the set of known objects, and proceed to Step 12.
|
|
232 |
|
|
233 |
8. If the object in the stream is an array, read its `ObjectStreamClass` and
|
|
234 |
the length of the array. Allocate the array, and add it and its handle in
|
|
235 |
the set of known objects. Read each element using the appropriate method
|
|
236 |
for its type and assign it to the array. Proceed to Step 12.
|
|
237 |
|
|
238 |
9. If the object in the stream is an enum constant, read its
|
|
239 |
`ObjectStreamClass` and the enum constant name. If the `ObjectStreamClass`
|
|
240 |
represents a class that is not an enum type, an `InvalidClassException` is
|
|
241 |
thrown. Obtain a reference to the enum constant by calling the
|
|
242 |
`java.lang.Enum.valueOf` method, passing the enum type bound to the
|
|
243 |
received `ObjectStreamClass` along with the received name as arguments. If
|
|
244 |
the `valueOf` method throws an `IllegalArgumentException`, an
|
|
245 |
`InvalidObjectException` is thrown with the `IllegalArgumentException` as
|
|
246 |
its cause. Add the enum constant and its handle in the set of known
|
|
247 |
objects, and proceed to Step 12.
|
|
248 |
|
|
249 |
10. For all other objects, the `ObjectStreamClass` of the object is read from
|
|
250 |
the stream. The local class for that `ObjectStreamClass` is retrieved. The
|
|
251 |
class must be serializable or externalizable, and must not be an enum type.
|
|
252 |
If the class does not satisfy these criteria, an `InvalidClassException` is
|
|
253 |
thrown.
|
|
254 |
|
|
255 |
11. An instance of the class is allocated. The instance and its handle are
|
|
256 |
added to the set of known objects. The contents restored appropriately:
|
|
257 |
|
|
258 |
a. For serializable objects, the no-arg constructor for the first
|
|
259 |
non-serializable supertype is run. For serializable classes, the fields
|
|
260 |
are initialized to the default value appropriate for its type. Then the
|
|
261 |
fields of each class are restored by calling class-specific
|
|
262 |
`readObject` methods, or if these are not defined, by calling the
|
|
263 |
`defaultReadObject` method. Note that field initializers and
|
|
264 |
constructors are not executed for serializable classes during
|
|
265 |
deserialization. In the normal case, the version of the class that
|
|
266 |
wrote the stream will be the same as the class reading the stream. In
|
|
267 |
this case, all of the supertypes of the object in the stream will match
|
|
268 |
the supertypes in the currently-loaded class. If the version of the
|
|
269 |
class that wrote the stream had different supertypes than the loaded
|
|
270 |
class, the `ObjectInputStream` must be more careful about restoring or
|
|
271 |
initializing the state of the differing classes. It must step through
|
|
272 |
the classes, matching the available data in the stream with the classes
|
|
273 |
of the object being restored. Data for classes that occur in the
|
|
274 |
stream, but do not occur in the object, is discarded. For classes that
|
|
275 |
occur in the object, but not in the stream, the class fields are set to
|
|
276 |
default values by default serialization.
|
|
277 |
|
|
278 |
b. For externalizable objects, the no-arg constructor for the class is run
|
|
279 |
and then the `readExternal` method is called to restore the contents of
|
|
280 |
the object.
|
|
281 |
|
|
282 |
12. Process potential substitutions by the class of the object and/or by a
|
|
283 |
subclass of `ObjectInputStream`:
|
|
284 |
|
|
285 |
a. If the class of the object is not an enum type and defines the
|
|
286 |
appropriate `readResolve` method, the method is called to allow the
|
|
287 |
object to replace itself.
|
|
288 |
|
|
289 |
b. Then if previously enabled by `enableResolveObject,` the
|
|
290 |
`resolveObject` method is called to allow subclasses of the stream to
|
|
291 |
examine and replace the object. If the previous step did replace the
|
|
292 |
original object, the `resolveObject` method is called with the
|
|
293 |
replacement object. If a replacement took place, the table of known
|
|
294 |
objects is updated so the replacement object is associated with the
|
|
295 |
handle. The replacement object is then returned from `readObject`.
|
|
296 |
|
|
297 |
All of the methods for reading primitives types only consume bytes from the
|
|
298 |
block data records in the stream. If a read for primitive data occurs when the
|
|
299 |
next item in the stream is an object, the read methods return *-1* or the
|
|
300 |
`EOFException` as appropriate. The value of a primitive type is read by a
|
|
301 |
`DataInputStream` from the block data record.
|
|
302 |
|
|
303 |
The exceptions thrown reflect errors during the traversal or exceptions that
|
|
304 |
occur on the underlying stream. If any exception is thrown, the underlying
|
|
305 |
stream is left in an unknown and unusable state.
|
|
306 |
|
|
307 |
When the reset token occurs in the stream, all of the state of the stream is
|
|
308 |
discarded. The set of known objects is cleared.
|
|
309 |
|
|
310 |
When the exception token occurs in the stream, the exception is read and a new
|
|
311 |
`WriteAbortedException` is thrown with the terminating exception as an
|
|
312 |
argument. The stream context is reset as described earlier.
|
|
313 |
|
|
314 |
The `readUnshared` method is used to read "unshared" objects from the stream.
|
|
315 |
This method is identical to `readObject`, except that it prevents subsequent
|
|
316 |
calls to `readObject` and `readUnshared` from returning additional references
|
|
317 |
to the deserialized instance returned by the original call to `readUnshared`.
|
|
318 |
Specifically:
|
|
319 |
|
|
320 |
- If `readUnshared` is called to deserialize a back-reference (the stream
|
|
321 |
representation of an object which has been written previously to the
|
|
322 |
stream), an `ObjectStreamException` will be thrown.
|
|
323 |
|
|
324 |
- If `readUnshared` returns successfully, then any subsequent attempts to
|
|
325 |
deserialize back-references to the stream handle deserialized by
|
|
326 |
`readUnshared` will cause an `ObjectStreamException` to be thrown.
|
|
327 |
|
|
328 |
Deserializing an object via `readUnshared` invalidates the stream handle
|
|
329 |
associated with the returned object. Note that this in itself does not always
|
|
330 |
guarantee that the reference returned by `readUnshared` is unique; the
|
|
331 |
deserialized object may define a `readResolve` method which returns an object
|
|
332 |
visible to other parties, or `readUnshared` may return a `Class` object or enum
|
|
333 |
constant obtainable elsewhere in the stream or through external means. If the
|
|
334 |
deserialized object defines a `readResolve` method and the invocation of that
|
|
335 |
method returns an array, then `readUnshared` returns a shallow clone of that
|
|
336 |
array; this guarantees that the returned array object is unique and cannot be
|
|
337 |
obtained a second time from an invocation of `readObject` or `readUnshared` on
|
|
338 |
the `ObjectInputStream`, even if the underlying data stream has been
|
|
339 |
manipulated.
|
|
340 |
|
|
341 |
The `defaultReadObject` method is used to read the fields and object from the
|
|
342 |
stream. It uses the class descriptor in the stream to read the fields in the
|
|
343 |
canonical order by name and type from the stream. The values are assigned to
|
|
344 |
the matching fields by name in the current class. Details of the versioning
|
|
345 |
mechanism can be found in [Section 5.5, "Compatible Java Type
|
|
346 |
Evolution"](version.html#compatible-java-type-evolution). Any field of the
|
|
347 |
object that does not appear in the stream is set to its default value. Values
|
|
348 |
that appear in the stream, but not in the object, are discarded. This occurs
|
|
349 |
primarily when a later version of a class has written additional fields that do
|
|
350 |
not occur in the earlier version. This method may only be called from the
|
|
351 |
`readObject` method while restoring the fields of a class. When called at any
|
|
352 |
other time, the `NotActiveException` is thrown.
|
|
353 |
|
|
354 |
The `readFields` method reads the values of the serializable fields from the
|
|
355 |
stream and makes them available via the `GetField` class. The `readFields`
|
|
356 |
method is only callable from within the `readObject` method of a serializable
|
|
357 |
class. It cannot be called more than once or if `defaultReadObject` has been
|
|
358 |
called. The `GetFields` object uses the current object's `ObjectStreamClass` to
|
|
359 |
verify the fields that can be retrieved for this class. The `GetFields` object
|
|
360 |
returned by `readFields` is only valid during this call to the classes
|
|
361 |
`readObject` method. The fields may be retrieved in any order. Additional data
|
|
362 |
may only be read directly from stream after `readFields` has been called.
|
|
363 |
|
|
364 |
The `registerValidation` method can be called to request a callback when the
|
|
365 |
entire graph has been restored but before the object is returned to the
|
|
366 |
original caller of `readObject`. The order of validate callbacks can be
|
|
367 |
controlled using the priority. Callbacks registered with higher values are
|
|
368 |
called before those with lower values. The object to be validated must support
|
|
369 |
the `ObjectInputValidation` interface and implement the `validateObject`
|
|
370 |
method. It is only correct to register validations during a call to a class's
|
|
371 |
`readObject` method. Otherwise, a `NotActiveException` is thrown. If the
|
|
372 |
callback object supplied to `registerValidation` is null, an
|
|
373 |
`InvalidObjectException` is thrown.
|
|
374 |
|
|
375 |
Starting with the Java SDK, Standard Edition, v1.3, the `readClassDescriptor`
|
|
376 |
method is used to read in all `ObjectStreamClass` objects.
|
|
377 |
`readClassDescriptor` is called when the `ObjectInputStream` expects a class
|
|
378 |
descriptor as the next item in the serialization stream. Subclasses of
|
|
379 |
`ObjectInputStream` may override this method to read in class descriptors that
|
|
380 |
have been written in non-standard formats (by subclasses of
|
|
381 |
`ObjectOutputStream` which have overridden the `writeClassDescriptor` method).
|
|
382 |
By default, this method reads class descriptors according to the format
|
|
383 |
described in [Section 6.4, "Grammar for the Stream
|
|
384 |
Format"](protocol.html#grammar-for-the-stream-format).
|
|
385 |
|
|
386 |
The `resolveClass` method is called while a class is being deserialized, and
|
|
387 |
after the class descriptor has been read. Subclasses may extend this method to
|
|
388 |
read other information about the class written by the corresponding subclass of
|
|
389 |
`ObjectOutputStream`. The method must find and return the class with the given
|
|
390 |
name and `serialVersionUID`. The default implementation locates the class by
|
|
391 |
calling the class loader of the closest caller of `readObject` that has a class
|
|
392 |
loader. If the class cannot be found `ClassNotFoundException` should be thrown.
|
|
393 |
Prior to JDK 1.1.6, the `resolveClass` method was required to return the same
|
|
394 |
fully qualified class name as the class name in the stream. In order to
|
|
395 |
accommodate package renaming across releases, `method` `resolveClass` only
|
|
396 |
needs to return a class with the same base class name and `SerialVersionUID` in
|
|
397 |
JDK 1.1.6 and later versions.
|
|
398 |
|
|
399 |
The `resolveObject` method is used by trusted subclasses to monitor or
|
|
400 |
substitute one object for another during deserialization. Resolving objects
|
|
401 |
must be enabled explicitly by calling `enableResolveObject` before calling
|
|
402 |
`readObject` for the first object to be resolved. Once enabled, `resolveObject`
|
|
403 |
is called once for each serializable object just prior to the first time it is
|
|
404 |
being returned from `readObject`. Note that the `resolveObject` method is not
|
|
405 |
called for objects of the specially handled classes, `Class`,
|
|
406 |
`ObjectStreamClass`, `String`, and arrays. A subclass's implementation of
|
|
407 |
`resolveObject` may return a substitute object that will be assigned or
|
|
408 |
returned instead of the original. The object returned must be of a type that is
|
|
409 |
consistent and assignable to every reference of the original object or else a
|
|
410 |
`ClassCastException` will be thrown. All assignments are type-checked. All
|
|
411 |
references in the stream to the original object will be replaced by references
|
|
412 |
to the substitute object.
|
|
413 |
|
|
414 |
The `enableResolveObject` method is called by trusted subclasses of
|
|
415 |
`ObjectOutputStream` to enable the monitoring or substitution of one object for
|
|
416 |
another during deserialization. Replacing objects is disabled until
|
|
417 |
`enableResolveObject` is called with a `true` value. It may thereafter be
|
|
418 |
disabled by setting it to `false`. The previous setting is returned. The
|
|
419 |
`enableResolveObject` method checks if the stream has permission to request
|
|
420 |
substitution during serialization. To ensure that the private state of objects
|
|
421 |
is not unintentionally exposed, only trusted streams may use `resolveObject`.
|
|
422 |
Trusted classes are those classes with a class loader equal to null or belong
|
|
423 |
to a security protection domain that provides permission to enable
|
|
424 |
substitution.
|
|
425 |
|
|
426 |
If the subclass of `ObjectInputStream` is not considered part of the system
|
|
427 |
domain, a line has to be added to the security policy file to provide to a
|
|
428 |
subclass of `ObjectInputStream` permission to call `enableResolveObject`. The
|
|
429 |
`SerializablePermission` to add is `"enableSubstitution"`.
|
|
430 |
`AccessControlException` is thrown if the protection domain of the subclass of
|
|
431 |
`ObjectStreamClass` does not have permission to `"enableSubstitution"` by
|
|
432 |
calling `enableResolveObject`. See the document Java Security Architecture (JDK
|
|
433 |
1.2) for additional information about the security model.
|
|
434 |
|
|
435 |
The `readStreamHeader` method reads and verifies the magic number and version
|
|
436 |
of the stream. If they do not match, the `StreamCorruptedMismatch` is thrown.
|
|
437 |
|
|
438 |
To override the implementation of deserialization, a subclass of
|
|
439 |
`ObjectInputStream` should call the protected no-arg `ObjectInputStream`,
|
|
440 |
constructor. There is a security check within the no-arg constructor for
|
|
441 |
`SerializablePermission "enableSubclassImplementation"` to ensure that only
|
|
442 |
trusted classes are allowed to override the default implementation. This
|
|
443 |
constructor does not allocate any private data for `ObjectInputStream` and sets
|
|
444 |
a flag that indicates that the final `readObject` method should invoke the
|
|
445 |
`readObjectOverride` method and return. All other `ObjectInputStream` methods
|
|
446 |
are not final and can be directly overridden by the subclass.
|
|
447 |
|
|
448 |
## 3.2 The ObjectInputStream.GetField Class
|
|
449 |
|
|
450 |
The class `ObjectInputStream.GetField` provides the API for getting the values
|
|
451 |
of serializable fields. The protocol of the stream is the same as used by
|
|
452 |
`defaultReadObject.` Using `readFields` to access the serializable fields does
|
|
453 |
not change the format of the stream. It only provides an alternate API to
|
|
454 |
access the values which does not require the class to have the corresponding
|
|
455 |
non-transient and non-static fields for each named serializable field. The
|
|
456 |
serializable fields are those declared using `serialPersistentFields` or if it
|
|
457 |
is not declared the non-transient and non-static fields of the object. When the
|
|
458 |
stream is read the available serializable fields are those written to the
|
|
459 |
stream when the object was serialized. If the class that wrote the stream is a
|
|
460 |
different version not all fields will correspond to the serializable fields of
|
|
461 |
the current class. The available fields can be retrieved from the
|
|
462 |
`ObjectStreamClass` of the `GetField` object.
|
|
463 |
|
|
464 |
The `getObjectStreamClass` method returns an `ObjectStreamClass` object
|
|
465 |
representing the class in the stream. It contains the list of serializable
|
|
466 |
fields.
|
|
467 |
|
|
468 |
The `defaulted` method returns *true* if the field is not present in the
|
|
469 |
stream. An `IllegalArgumentException` is thrown if the requested field is not a
|
|
470 |
serializable field of the current class.
|
|
471 |
|
|
472 |
Each `get` method returns the specified serializable field from the stream. I/O
|
|
473 |
exceptions will be thrown if the underlying stream throws an exception. An
|
|
474 |
`IllegalArgumentException` is thrown if the name or type does not match the
|
|
475 |
name and type of an field serializable field of the current class. The default
|
|
476 |
value is returned if the stream does not contain an explicit value for the
|
|
477 |
field.
|
|
478 |
|
|
479 |
## 3.3 The ObjectInputValidation Interface
|
|
480 |
|
|
481 |
This interface allows an object to be called when a complete graph of objects
|
|
482 |
has been deserialized. If the object cannot be made valid, it should throw the
|
|
483 |
`ObjectInvalidException`. Any exception that occurs during a call to
|
|
484 |
`validateObject` will terminate the validation process, and the
|
|
485 |
`InvalidObjectException` will be thrown.
|
|
486 |
|
|
487 |
```
|
|
488 |
package java.io;
|
|
489 |
|
|
490 |
public interface ObjectInputValidation
|
|
491 |
{
|
|
492 |
public void validateObject()
|
|
493 |
throws InvalidObjectException;
|
|
494 |
}
|
|
495 |
```
|
|
496 |
|
|
497 |
## 3.4 The readObject Method
|
|
498 |
|
|
499 |
For serializable objects, the `readObject` method allows a class to control the
|
|
500 |
deserialization of its own fields. Here is its signature:
|
|
501 |
|
|
502 |
```
|
|
503 |
private void readObject(ObjectInputStream stream)
|
|
504 |
throws IOException, ClassNotFoundException;
|
|
505 |
```
|
|
506 |
|
|
507 |
Each subclass of a serializable object may define its own `readObject` method.
|
|
508 |
If a class does not implement the method, the default serialization provided by
|
|
509 |
`defaultReadObject` will be used. When implemented, the class is only
|
|
510 |
responsible for restoring its own fields, not those of its supertypes or
|
|
511 |
subtypes.
|
|
512 |
|
|
513 |
The `readObject` method of the class, if implemented, is responsible for
|
|
514 |
restoring the state of the class. The values of every field of the object
|
|
515 |
whether transient or not, static or not are set to the default value for the
|
|
516 |
fields type. Either `ObjectInputStream`'s `defaultReadObject` or `readFields`
|
|
517 |
method must be called once (and only once) before reading any optional data
|
|
518 |
written by the corresponding `writeObject` method; even if no optional data is
|
|
519 |
read, `defaultReadObject` or `readFields` must still be invoked once. If the
|
|
520 |
`readObject` method of the class attempts to read more data than is present in
|
|
521 |
the optional part of the stream for this class, the stream will return `-1` for
|
|
522 |
bytewise reads, throw an `EOFException` for primitive data reads (e.g.,
|
|
523 |
`readInt`, `readFloat`), or throw an `OptionalDataException` with the `eof`
|
|
524 |
field set to `true` for object reads.
|
|
525 |
|
|
526 |
The responsibility for the format, structure, and versioning of the optional
|
|
527 |
data lies completely with the class. The `@serialData` javadoc tag within the
|
|
528 |
javadoc comment for the `readObject` method should be used to document the
|
|
529 |
format and structure of the optional data.
|
|
530 |
|
|
531 |
If the class being restored is not present in the stream being read, then its
|
|
532 |
`readObjectNoData` method, if defined, is invoked (instead of `readObject`);
|
|
533 |
otherwise, its fields are initialized to the appropriate default values. For
|
|
534 |
further detail, see [Section 3.5, "The readObjectNoData
|
|
535 |
Method"](#the-readobjectnodata-method).
|
|
536 |
|
|
537 |
Reading an object from the `ObjectInputStream` is analogous to creating a new
|
|
538 |
object. Just as a new object's constructors are invoked in the order from the
|
|
539 |
superclass to the subclass, an object being read from a stream is deserialized
|
|
540 |
from superclass to subclass. The `readObject` or `readObjectNoData` method is
|
|
541 |
called instead of the constructor for each `Serializable` subclass during
|
|
542 |
deserialization.
|
|
543 |
|
|
544 |
One last similarity between a constructor and a `readObject` method is that
|
|
545 |
both provide the opportunity to invoke a method on an object that is not fully
|
|
546 |
constructed. Any overridable (neither private, static nor final) method called
|
|
547 |
while an object is being constructed can potentially be overridden by a
|
|
548 |
subclass. Methods called during the construction phase of an object are
|
|
549 |
resolved by the actual type of the object, not the type currently being
|
|
550 |
initialized by either its constructor or `readObject`/`readObjectNoData`
|
|
551 |
method. Therefore, calling an overridable method from within a `readObject` or
|
|
552 |
`readObjectNoData` method may result in the unintentional invocation of a
|
|
553 |
subclass method before the superclass has been fully initialized.
|
|
554 |
|
|
555 |
## 3.5 The readObjectNoData Method
|
|
556 |
|
|
557 |
For serializable objects, the `readObjectNoData` method allows a class to
|
|
558 |
control the initialization of its own fields in the event that a subclass
|
|
559 |
instance is deserialized and the serialization stream does not list the class
|
|
560 |
in question as a superclass of the deserialized object. This may occur in cases
|
|
561 |
where the receiving party uses a different version of the deserialized
|
|
562 |
instance's class than the sending party, and the receiver's version extends
|
|
563 |
classes that are not extended by the sender's version. This may also occur if
|
|
564 |
the serialization stream has been tampered; hence, `readObjectNoData` is useful
|
|
565 |
for initializing deserialized objects properly despite a "hostile" or
|
|
566 |
incomplete source stream.
|
|
567 |
|
|
568 |
```
|
|
569 |
private void readObjectNoData() throws ObjectStreamException;
|
|
570 |
```
|
|
571 |
|
|
572 |
Each serializable class may define its own `readObjectNoData` method. If a
|
|
573 |
serializable class does not define a `readObjectNoData` method, then in the
|
|
574 |
circumstances listed above the fields of the class will be initialized to their
|
|
575 |
default values (as listed in The Java Language Specification); this behavior is
|
|
576 |
consistent with that of `ObjectInputStream` prior to version 1.4 of the Java 2
|
|
577 |
SDK, Standard Edition, when support for `readObjectNoData` methods was
|
|
578 |
introduced. If a serializable class does define a `readObjectNoData` method and
|
|
579 |
the aforementioned conditions arise, then `readObjectNoData` will be invoked at
|
|
580 |
the point during deserialization when a class-defined `readObject` method would
|
|
581 |
otherwise be called had the class in question been listed by the stream as a
|
|
582 |
superclass of the instance being deserialized.
|
|
583 |
|
|
584 |
## 3.6 The readExternal Method
|
|
585 |
|
|
586 |
Objects implementing `java.io.Externalizable` must implement the `readExternal`
|
|
587 |
method to restore the entire state of the object. It must coordinate with its
|
|
588 |
superclasses to restore their state. All of the methods of `ObjectInput` are
|
|
589 |
available to restore the object's primitive typed fields and object fields.
|
|
590 |
|
|
591 |
```
|
|
592 |
public void readExternal(ObjectInput stream)
|
|
593 |
throws IOException;
|
|
594 |
```
|
|
595 |
|
|
596 |
**Note:** The `readExternal` method is public, and it raises the risk of a
|
|
597 |
client being able to overwrite an existing object from a stream. The class may
|
|
598 |
add its own checks to insure that this is only called when appropriate.
|
|
599 |
|
|
600 |
A new stream protocol version has been introduced in JDK 1.2 to correct a
|
|
601 |
problem with `Externalizable` objects. The old definition of `Externalizable`
|
|
602 |
objects required the local virtual machine to find a `readExternal` method to
|
|
603 |
be able to properly read an `Externalizable` object from the stream. The new
|
|
604 |
format adds enough information to the stream protocol so serialization can skip
|
|
605 |
an `Externalizable` object when the local `readExternal` method is not
|
|
606 |
available. Due to class evolution rules, serialization must be able to skip an
|
|
607 |
`Externalizable` object in the input stream if there is not a mapping for the
|
|
608 |
object using the local classes.
|
|
609 |
|
|
610 |
An additional benefit of the new `Externalizable` stream format is that
|
|
611 |
`ObjectInputStream` can detect attempts to read more External data than is
|
|
612 |
available, and can also skip by any data that is left unconsumed by a
|
|
613 |
`readExternal` method. The behavior of `ObjectInputStream` in response to a
|
|
614 |
read past the end of External data is the same as the behavior when a
|
|
615 |
class-defined `readObject` method attempts to read past the end of its optional
|
|
616 |
data: bytewise reads will return `-1`, primitive reads will throw
|
|
617 |
`EOFException`s, and object reads will throw `OptionalDataException`s with the
|
|
618 |
`eof` field set to `true`.
|
|
619 |
|
|
620 |
Due to the format change, JDK 1.1.6 and earlier releases are not able to read
|
|
621 |
the new format. `StreamCorruptedException` is thrown when JDK 1.1.6 or earlier
|
|
622 |
attempts to read an `Externalizable` object from a stream written in
|
|
623 |
`PROTOCOL_VERSION_2`. Compatibility issues are discussed in more detail in
|
|
624 |
[Section 6.3, "Stream Protocol
|
|
625 |
Versions"](protocol.html#stream-protocol-versions).
|
|
626 |
|
|
627 |
## 3.7 The readResolve Method
|
|
628 |
|
|
629 |
For Serializable and Externalizable classes, the `readResolve` method allows a
|
|
630 |
class to replace/resolve the object read from the stream before it is returned
|
|
631 |
to the caller. By implementing the `readResolve` method, a class can directly
|
|
632 |
control the types and instances of its own instances being deserialized. The
|
|
633 |
method is defined as follows:
|
|
634 |
|
|
635 |
```
|
|
636 |
ANY-ACCESS-MODIFIER Object readResolve()
|
|
637 |
throws ObjectStreamException;
|
|
638 |
```
|
|
639 |
|
|
640 |
The `readResolve` method is called when `ObjectInputStream` has read an object
|
|
641 |
from the stream and is preparing to return it to the caller.
|
|
642 |
`ObjectInputStream` checks whether the class of the object defines the
|
|
643 |
`readResolve` method. If the method is defined, the `readResolve` method is
|
|
644 |
called to allow the object in the stream to designate the object to be
|
|
645 |
returned. The object returned should be of a type that is compatible with all
|
|
646 |
uses. If it is not compatible, a `ClassCastException` will be thrown when the
|
|
647 |
type mismatch is discovered.
|
|
648 |
|
|
649 |
For example, a `Symbol` class could be created for which only a single instance
|
|
650 |
of each symbol binding existed within a virtual machine. The `readResolve`
|
|
651 |
method would be implemented to determine if that symbol was already defined and
|
|
652 |
substitute the preexisting equivalent `Symbol` object to maintain the identity
|
|
653 |
constraint. In this way the uniqueness of `Symbol` objects can be maintained
|
|
654 |
across serialization.
|
|
655 |
|
|
656 |
**Note:** The `readResolve` method is not invoked on the object until the
|
|
657 |
object is fully constructed, so any references to this object in its object
|
|
658 |
graph will not be updated to the new object nominated by `readResolve`.
|
|
659 |
However, during the serialization of an object with the `writeReplace` method,
|
|
660 |
all references to the original object in the replacement object's object graph
|
|
661 |
are replaced with references to the replacement object. Therefore in cases
|
|
662 |
where an object being serialized nominates a replacement object whose object
|
|
663 |
graph has a reference to the original object, deserialization will result in an
|
|
664 |
incorrect graph of objects. Furthermore, if the reference types of the object
|
|
665 |
being read (nominated by `writeReplace`) and the original object are not
|
|
666 |
compatible, the construction of the object graph will raise a
|
|
667 |
`ClassCastException`.
|
|
668 |
|
|
669 |
-------------------------------------------------------------------------------
|
|
670 |
|
|
671 |
*[Copyright](../../../legal/SMICopyright.html) © 2005, 2017, Oracle
|
|
672 |
and/or its affiliates. All rights reserved.*
|