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](index.html) | [NEXT](output.html)' |
|
24 include-after: '[CONTENTS](index.html) | [PREV](index.html) | [NEXT](output.html)' |
|
25 |
|
26 title: 'Java Object Serialization Specification: 1 - System Architecture' |
|
27 --- |
|
28 |
|
29 - [Overview](#overview) |
|
30 - [Writing to an Object Stream](#writing-to-an-object-stream) |
|
31 - [Reading from an Object Stream](#reading-from-an-object-stream) |
|
32 - [Object Streams as Containers](#object-streams-as-containers) |
|
33 - [Defining Serializable Fields for a |
|
34 Class](#defining-serializable-fields-for-a-class) |
|
35 - [Documenting Serializable Fields and Data for a |
|
36 Class](#documenting-serializable-fields-and-data-for-a-class) |
|
37 - [Accessing Serializable Fields of a |
|
38 Class](#accessing-serializable-fields-of-a-class) |
|
39 - [The ObjectOutput Interface](#the-objectoutput-interface) |
|
40 - [The ObjectInput Interface](#the-objectinput-interface) |
|
41 - [The Serializable Interface](#the-serializable-interface) |
|
42 - [The Externalizable Interface](#the-externalizable-interface) |
|
43 - [Serialization of Enum Constants](#serialization-of-enum-constants) |
|
44 - [Protecting Sensitive Information](#protecting-sensitive-information) |
|
45 |
|
46 ------------------------------------------------------------------------------- |
|
47 |
|
48 ## 1.1 Overview |
|
49 |
|
50 The ability to store and retrieve Java^TM^ objects is essential to building all |
|
51 but the most transient applications. The key to storing and retrieving objects |
|
52 in a serialized form is representing the state of objects sufficient to |
|
53 reconstruct the object(s). Objects to be saved in the stream may support either |
|
54 the `Serializable` or the `Externalizable` interface. For Java^TM^ objects, the |
|
55 serialized form must be able to identify and verify the Java^TM^ class from |
|
56 which the contents of the object were saved and to restore the contents to a |
|
57 new instance. For serializable objects, the stream includes sufficient |
|
58 information to restore the fields in the stream to a compatible version of the |
|
59 class. For Externalizable objects, the class is solely responsible for the |
|
60 external format of its contents. |
|
61 |
|
62 Objects to be stored and retrieved frequently refer to other objects. Those |
|
63 other objects must be stored and retrieved at the same time to maintain the |
|
64 relationships between the objects. When an object is stored, all of the objects |
|
65 that are reachable from that object are stored as well. |
|
66 |
|
67 The goals for serializing Java^TM^ objects are to: |
|
68 |
|
69 - Have a simple yet extensible mechanism. |
|
70 - Maintain the Java^TM^ object type and safety properties in the serialized |
|
71 form. |
|
72 - Be extensible to support marshaling and unmarshaling as needed for remote |
|
73 objects. |
|
74 - Be extensible to support simple persistence of Java^TM^ objects. |
|
75 - Require per class implementation only for customization. |
|
76 - Allow the object to define its external format. |
|
77 |
|
78 ## 1.2 Writing to an Object Stream |
|
79 |
|
80 Writing objects and primitives to a stream is a straightforward process. For |
|
81 example: |
|
82 |
|
83 ``` |
|
84 // Serialize today's date to a file. |
|
85 FileOutputStream f = new FileOutputStream("tmp"); |
|
86 ObjectOutput s = new ObjectOutputStream(f); |
|
87 s.writeObject("Today"); |
|
88 s.writeObject(new Date()); |
|
89 s.flush(); |
|
90 ``` |
|
91 |
|
92 First an `OutputStream`, in this case a `FileOutputStream`, is needed to |
|
93 receive the bytes. Then an `ObjectOutputStream` is created that writes to the |
|
94 `FileOutputStream`. Next, the string "Today" and a Date object are written to |
|
95 the stream. More generally, objects are written with the `writeObject` method |
|
96 and primitives are written to the stream with the methods of `DataOutput`. |
|
97 |
|
98 The `writeObject` method (see [Section 2.3, "The writeObject |
|
99 Method"](output.html#the-writeobject-method)) serializes the specified object |
|
100 and traverses its references to other objects in the object graph recursively |
|
101 to create a complete serialized representation of the graph. Within a stream, |
|
102 the first reference to any object results in the object being serialized or |
|
103 externalized and the assignment of a handle for that object. Subsequent |
|
104 references to that object are encoded as the handle. Using object handles |
|
105 preserves sharing and circular references that occur naturally in object |
|
106 graphs. Subsequent references to an object use only the handle allowing a very |
|
107 compact representation. |
|
108 |
|
109 Special handling is required for arrays, enum constants, and objects of type |
|
110 `Class`, `ObjectStreamClass`, and `String`. Other objects must implement either |
|
111 the `Serializable` or the `Externalizable` interface to be saved in or restored |
|
112 from a stream. |
|
113 |
|
114 Primitive data types are written to the stream with the methods in the |
|
115 `DataOutput` interface, such as `writeInt`, `writeFloat`, or `writeUTF`. |
|
116 Individual bytes and arrays of bytes are written with the methods of |
|
117 `OutputStream`. Except for serializable fields, primitive data is written to |
|
118 the stream in block-data records, with each record prefixed by a marker and an |
|
119 indication of the number of bytes in the record. |
|
120 |
|
121 `ObjectOutputStream` can be extended to customize the information about classes |
|
122 in the stream or to replace objects to be serialized. Refer to the |
|
123 `annotateClass` and `replaceObject` method descriptions for details. |
|
124 |
|
125 ## 1.3 Reading from an Object Stream |
|
126 |
|
127 Reading an object from a stream, like writing, is straightforward: |
|
128 |
|
129 ``` |
|
130 // Deserialize a string and date from a file. |
|
131 FileInputStream in = new FileInputStream("tmp"); |
|
132 ObjectInputStream s = new ObjectInputStream(in); |
|
133 String today = (String)s.readObject(); |
|
134 Date date = (Date)s.readObject(); |
|
135 ``` |
|
136 |
|
137 First an `InputStream`, in this case a `FileInputStream`, is needed as the |
|
138 source stream. Then an `ObjectInputStream` is created that reads from the |
|
139 `InputStream`. Next, the string "Today" and a Date object are read from the |
|
140 stream. Generally, objects are read with the `readObject` method and primitives |
|
141 are read from the stream with the methods of `DataInput`. |
|
142 |
|
143 The `readObject` method deserializes the next object in the stream and |
|
144 traverses its references to other objects recursively to create the complete |
|
145 graph of objects serialized. |
|
146 |
|
147 Primitive data types are read from the stream with the methods in the |
|
148 `DataInput` interface, such as `readInt`, `readFloat`, or `readUTF`. Individual |
|
149 bytes and arrays of bytes are read with the methods of `InputStream`. Except |
|
150 for serializable fields, primitive data is read from block-data records. |
|
151 |
|
152 `ObjectInputStream` can be extended to utilize customized information in the |
|
153 stream about classes or to replace objects that have been deserialized. Refer |
|
154 to the `resolveClass` and `resolveObject` method descriptions for details. |
|
155 |
|
156 ## 1.4 Object Streams as Containers |
|
157 |
|
158 Object Serialization produces and consumes a stream of bytes that contain one |
|
159 or more primitives and objects. The objects written to the stream, in turn, |
|
160 refer to other objects, which are also represented in the stream. Object |
|
161 Serialization produces just one stream format that encodes and stores the |
|
162 contained objects. |
|
163 |
|
164 Each object that acts as a container implements an interface which allows |
|
165 primitives and objects to be stored in or retrieved from it. These interfaces |
|
166 are the `ObjectOutput` and `ObjectInput` interfaces which: |
|
167 |
|
168 - Provide a stream to write to and to read from |
|
169 - Handle requests to write primitive types and objects to the stream |
|
170 - Handle requests to read primitive types and objects from the stream |
|
171 |
|
172 Each object which is to be stored in a stream must explicitly allow itself to |
|
173 be stored and must implement the protocols needed to save and restore its |
|
174 state. Object Serialization defines two such protocols. The protocols allow the |
|
175 container to ask the object to write and read its state. |
|
176 |
|
177 To be stored in an Object Stream, each object must implement either the |
|
178 `Serializable` or the `Externalizable` interface: |
|
179 |
|
180 - For a `Serializable` class, Object Serialization can automatically save and |
|
181 restore fields of each class of an object and automatically handle classes |
|
182 that evolve by adding fields or supertypes. A serializable class can |
|
183 declare which of its fields are saved or restored, and write and read |
|
184 optional values and objects. |
|
185 |
|
186 - For an `Externalizable` class, Object Serialization delegates to the class |
|
187 complete control over its external format and how the state of the |
|
188 supertype(s) is saved and restored. |
|
189 |
|
190 ## 1.5 Defining Serializable Fields for a Class |
|
191 |
|
192 The serializable fields of a class can be defined two different ways. Default |
|
193 serializable fields of a class are defined to be the non-transient and |
|
194 non-static fields. This default computation can be overridden by declaring a |
|
195 special field in the `Serializable` class, `serialPersistentFields`. This field |
|
196 must be initialized with an array of `ObjectStreamField` objects that list the |
|
197 names and types of the serializable fields. The modifiers for the field are |
|
198 required to be private, static, and final. If the field's value is null or is |
|
199 otherwise not an instance of `ObjectStreamField[]`, or if the field does not |
|
200 have the required modifiers, then the behavior is as if the field were not |
|
201 declared at all. |
|
202 |
|
203 For example, the following declaration duplicates the default behavior. |
|
204 |
|
205 ``` |
|
206 class List implements Serializable { |
|
207 List next; |
|
208 |
|
209 private static final ObjectStreamField[] serialPersistentFields |
|
210 = {new ObjectStreamField("next", List.class)}; |
|
211 |
|
212 } |
|
213 ``` |
|
214 |
|
215 By using `serialPersistentFields` to define the Serializable fields for a |
|
216 class, there no longer is a limitation that a serializable field must be a |
|
217 field within the current definition of the `Serializable` class. The |
|
218 `writeObject` and `readObject` methods of the `Serializable` class can map the |
|
219 current implementation of the class to the serializable fields of the class |
|
220 using the interface that is described in [Section 1.7, "Accessing Serializable |
|
221 Fields of a Class"](#accessing-serializable-fields-of-a-class). Therefore, the |
|
222 fields for a `Serializable` class can change in a later release, as long as it |
|
223 maintains the mapping back to its Serializable fields that must remain |
|
224 compatible across release boundaries. |
|
225 |
|
226 **Note:** There is, however, a limitation to the use of this mechanism to |
|
227 specify serializable fields for inner classes. Inner classes can only contain |
|
228 final static fields that are initialized to constants or expressions built up |
|
229 from constants. Consequently, it is not possible to set |
|
230 `serialPersistentFields` for an inner class (though it is possible to set it |
|
231 for static member classes). For other restrictions pertaining to serialization |
|
232 of inner class instances, see section [Section 1.10, "The Serializable |
|
233 Interface"](#the-serializable-interface). |
|
234 |
|
235 ## 1.6 Documenting Serializable Fields and Data for a Class |
|
236 |
|
237 It is important to document the serializable state of a class to enable |
|
238 interoperability with alternative implementations of a Serializable class and |
|
239 to document class evolution. Documenting a serializable field gives one a final |
|
240 opportunity to review whether or not the field should be serializable. The |
|
241 serialization javadoc tags, `@serial`, `@serialField`, and `@serialData`, |
|
242 provide a way to document the serialized form for a Serializable class within |
|
243 the source code. |
|
244 |
|
245 - The `@serial` tag should be placed in the javadoc comment for a default |
|
246 serializable field. The syntax is as follows: `@serial` *field-description* |
|
247 The optional *field-description* describes the meaning of the field and its |
|
248 acceptable values. The *field-description* can span multiple lines. When a |
|
249 field is added after the initial release, a *@since* tag indicates the |
|
250 version the field was added. The *field-description* for `@serial` provides |
|
251 serialization-specific documentation and is appended to the javadoc comment |
|
252 for the field within the serialized form documentation. |
|
253 |
|
254 - The `@serialField` tag is used to document an `ObjectStreamField` component |
|
255 of a `serialPersistentFields` array. One of these tags should be used for |
|
256 each `ObjectStreamField` component. The syntax is as follows: |
|
257 `@serialField` *field-name field-type field-description* |
|
258 |
|
259 - The `@serialData` tag describes the sequences and types of data written or |
|
260 read. The tag describes the sequence and type of optional data written by |
|
261 `writeObject` or all data written by the `Externalizable.writeExternal` |
|
262 method. The syntax is as follows: `@serialData` *data-description* |
|
263 |
|
264 The javadoc application recognizes the serialization javadoc tags and generates |
|
265 a specification for each Serializable and Externalizable class. See [Section |
|
266 C.1, "Example Alternate Implementation of |
|
267 java.io.File"](examples.html#c.1-example-alternate-implementation-of-java.io.file) |
|
268 for an example that uses these tags. |
|
269 |
|
270 When a class is declared Serializable, the serializable state of the object is |
|
271 defined by serializable fields (by name and type) plus optional data. Optional |
|
272 data can only be written explicitly by the `writeObject` method of a |
|
273 `Serializable` class. Optional data can be read by the `Serializable` class' |
|
274 `readObject` method or serialization will skip unread optional data. |
|
275 |
|
276 When a class is declared Externalizable, the data that is written to the stream |
|
277 by the class itself defines the serialized state. The class must specify the |
|
278 order, types, and meaning of each datum that is written to the stream. The |
|
279 class must handle its own evolution, so that it can continue to read data |
|
280 written by and write data that can be read by previous versions. The class must |
|
281 coordinate with the superclass when saving and restoring data. The location of |
|
282 the superclasses data in the stream must be specified. |
|
283 |
|
284 The designer of a Serializable class must ensure that the information saved for |
|
285 the class is appropriate for persistence and follows the |
|
286 serialization-specified rules for interoperability and evolution. Class |
|
287 evolution is explained in greater detail in [Chapter |
|
288 5](version.html#versioning-of-serializable-objects), "Versioning of |
|
289 Serializable Objects". |
|
290 |
|
291 ## 1.7 Accessing Serializable Fields of a Class |
|
292 |
|
293 Serialization provides two mechanisms for accessing the serializable fields in |
|
294 a stream: |
|
295 |
|
296 - The default mechanism requires no customization |
|
297 - The Serializable Fields API allows a class to explicitly access/set the |
|
298 serializable fields by name and type |
|
299 |
|
300 The default mechanism is used automatically when reading or writing objects |
|
301 that implement the `Serializable` interface and do no further customization. |
|
302 The serializable fields are mapped to the corresponding fields of the class and |
|
303 values are either written to the stream from those fields or are read in and |
|
304 assigned respectively. If the class provides `writeObject` and `readObject` |
|
305 methods, the default mechanism can be invoked by calling `defaultWriteObject` |
|
306 and `defaultReadObject`. When the `writeObject` and `readObject` methods are |
|
307 implemented, the class has an opportunity to modify the serializable field |
|
308 values before they are written or after they are read. |
|
309 |
|
310 When the default mechanism cannot be used, the serializable class can use the |
|
311 `putFields` method of `ObjectOutputStream` to put the values for the |
|
312 serializable fields into the stream. The `writeFields` method of |
|
313 `ObjectOutputStream` puts the values in the correct order, then writes them to |
|
314 the stream using the existing protocol for serialization. Correspondingly, the |
|
315 `readFields` method of `ObjectInputStream` reads the values from the stream and |
|
316 makes them available to the class by name in any order. See [Section 2.2, "The |
|
317 ObjectOutputStream.PutField |
|
318 Class"](output.html#the-objectoutputstream.putfield-class) and [Section 3.2, |
|
319 "The ObjectInputStream.GetField |
|
320 Class"](input.html#the-objectinputstream.getfield-class) for a detailed |
|
321 description of the Serializable Fields API. |
|
322 |
|
323 ## 1.8 The ObjectOutput Interface |
|
324 |
|
325 The `ObjectOutput` interface provides an abstract, stream-based interface to |
|
326 object storage. It extends the DataOutput interface so those methods can be |
|
327 used for writing primitive data types. Objects that implement this interface |
|
328 can be used to store primitives and objects. |
|
329 |
|
330 ``` |
|
331 package java.io; |
|
332 |
|
333 public interface ObjectOutput extends DataOutput |
|
334 { |
|
335 public void writeObject(Object obj) throws IOException; |
|
336 public void write(int b) throws IOException; |
|
337 public void write(byte b[]) throws IOException; |
|
338 public void write(byte b[], int off, int len) throws IOException; |
|
339 public void flush() throws IOException; |
|
340 public void close() throws IOException; |
|
341 } |
|
342 ``` |
|
343 |
|
344 `The` `writeObject` method is used to write an object. The exceptions thrown |
|
345 reflect errors while accessing the object or its fields, or exceptions that |
|
346 occur in writing to storage. If any exception is thrown, the underlying storage |
|
347 may be corrupted. If this occurs, refer to the object that is implementing this |
|
348 interface for more information. |
|
349 |
|
350 ## 1.9 The ObjectInput Interface |
|
351 |
|
352 The `ObjectInput` interface provides an abstract stream based interface to |
|
353 object retrieval. It extends the `DataInput` interface so those methods for |
|
354 reading primitive data types are accessible in this interface. |
|
355 |
|
356 ``` |
|
357 package java.io; |
|
358 |
|
359 public interface ObjectInput extends DataInput |
|
360 { |
|
361 public Object readObject() |
|
362 throws ClassNotFoundException, IOException; |
|
363 public int read() throws IOException; |
|
364 public int read(byte b[]) throws IOException; |
|
365 public int read(byte b[], int off, int len) throws IOException; |
|
366 public long skip(long n) throws IOException; |
|
367 public int available() throws IOException; |
|
368 public void close() throws IOException; |
|
369 } |
|
370 ``` |
|
371 |
|
372 The `readObject` method is used to read and return an object. The exceptions |
|
373 thrown reflect errors while accessing the objects or its fields or exceptions |
|
374 that occur in reading from the storage. If any exception is thrown, the |
|
375 underlying storage may be corrupted. If this occurs, refer to the object |
|
376 implementing this interface for additional information. |
|
377 |
|
378 ## 1.10 The Serializable Interface |
|
379 |
|
380 Object Serialization produces a stream with information about the Java^TM^ |
|
381 classes for the objects which are being saved. For serializable objects, |
|
382 sufficient information is kept to restore those objects even if a different |
|
383 (but compatible) version of the implementation of the class is present. The |
|
384 `Serializable` interface is defined to identify classes which implement the |
|
385 serializable protocol: |
|
386 |
|
387 ``` |
|
388 package java.io; |
|
389 |
|
390 public interface Serializable {}; |
|
391 ``` |
|
392 |
|
393 A Serializable class must do the following: |
|
394 |
|
395 - Implement the `java.io.Serializable` interface |
|
396 |
|
397 - Identify the fields that should be serializable |
|
398 |
|
399 (Use the `serialPersistentFields` member to explicitly declare them |
|
400 serializable or use the transient keyword to denote nonserializable |
|
401 fields.) |
|
402 |
|
403 - Have access to the no-arg constructor of its first nonserializable |
|
404 superclass |
|
405 |
|
406 The class can optionally define the following methods: |
|
407 |
|
408 - A `writeObject` method to control what information is saved or to append |
|
409 additional information to the stream |
|
410 |
|
411 - A `readObject` method either to read the information written by the |
|
412 corresponding `writeObject` method or to update the state of the object |
|
413 after it has been restored |
|
414 |
|
415 - A `writeReplace` method to allow a class to nominate a replacement object |
|
416 to be written to the stream |
|
417 |
|
418 (See [Section 2.5, "The writeReplace |
|
419 Method"](output.html#the-writereplace-method) for additional information.) |
|
420 |
|
421 - A `readResolve` method to allow a class to designate a replacement object |
|
422 for the object just read from the stream |
|
423 |
|
424 (See [Section 3.7, "The readResolve |
|
425 Method](input.html#the-readresolve-method) for additional information.) |
|
426 |
|
427 `ObjectOutputStream` and `ObjectInputStream` allow the serializable classes on |
|
428 which they operate to evolve (allow changes to the classes that are compatible |
|
429 with the earlier versions of the classes). See [Section 5.5, "Compatible Java |
|
430 Type Evolution"](version.html#compatible-java-type-evolution) for information |
|
431 about the mechanism which is used to allow compatible changes. |
|
432 |
|
433 **Note:** Serialization of inner classes (i.e., nested classes that are not |
|
434 static member classes), including local and anonymous classes, is strongly |
|
435 discouraged for several reasons. Because inner classes declared in non-static |
|
436 contexts contain implicit non-transient references to enclosing class |
|
437 instances, serializing such an inner class instance will result in |
|
438 serialization of its associated outer class instance as well. Synthetic fields |
|
439 generated by `javac` (or other Java^TM^ compilers) to implement inner classes |
|
440 are implementation dependent and may vary between compilers; differences in |
|
441 such fields can disrupt compatibility as well as result in conflicting default |
|
442 `serialVersionUID` values. The names assigned to local and anonymous inner |
|
443 classes are also implementation dependent and may differ between compilers. |
|
444 Since inner classes cannot declare static members other than compile-time |
|
445 constant fields, they cannot use the `serialPersistentFields` mechanism to |
|
446 designate serializable fields. Finally, because inner classes associated with |
|
447 outer instances do not have zero-argument constructors (constructors of such |
|
448 inner classes implicitly accept the enclosing instance as a prepended |
|
449 parameter), they cannot implement `Externalizable`. None of the issues listed |
|
450 above, however, apply to static member classes. |
|
451 |
|
452 ## 1.11 The Externalizable Interface |
|
453 |
|
454 For Externalizable objects, only the identity of the class of the object is |
|
455 saved by the container; the class must save and restore the contents. The |
|
456 `Externalizable` interface is defined as follows: |
|
457 |
|
458 ``` |
|
459 package java.io; |
|
460 |
|
461 public interface Externalizable extends Serializable |
|
462 { |
|
463 public void writeExternal(ObjectOutput out) |
|
464 throws IOException; |
|
465 |
|
466 public void readExternal(ObjectInput in) |
|
467 throws IOException, java.lang.ClassNotFoundException; |
|
468 } |
|
469 ``` |
|
470 |
|
471 The class of an Externalizable object must do the following: |
|
472 |
|
473 - Implement the `java.io.Externalizable` interface |
|
474 |
|
475 - Implement a `writeExternal` method to save the state of the object |
|
476 |
|
477 (It must explicitly coordinate with its supertype to save its state.) |
|
478 |
|
479 - Implement a `readExternal` method to read the data written by the |
|
480 `writeExternal` method from the stream and restore the state of the object |
|
481 |
|
482 (It must explicitly coordinate with the supertype to save its state.) |
|
483 |
|
484 - Have the `writeExternal` and `readExternal` methods be solely responsible |
|
485 for the format, if an externally defined format is written |
|
486 |
|
487 **Note:** The `writeExternal` and `readExternal` methods are public and |
|
488 raise the risk that a client may be able to write or read information in |
|
489 the object other than by using its methods and fields. These methods must |
|
490 be used only when the information held by the object is not sensitive or |
|
491 when exposing it does not present a security risk. |
|
492 |
|
493 - Have a public no-arg constructor |
|
494 |
|
495 **Note:** Inner classes associated with enclosing instances cannot have |
|
496 no-arg constructors, since constructors of such classes implicitly accept |
|
497 the enclosing instance as a prepended parameter. Consequently the |
|
498 `Externalizable` interface mechanism cannot be used for inner classes and |
|
499 they should implement the `Serializable` interface, if they must be |
|
500 serialized. Several limitations exist for serializable inner classes as |
|
501 well, however; see [Section 1.10, "The Serializable |
|
502 Interface"](#the-serializable-interface), for a full enumeration. |
|
503 |
|
504 An Externalizable class can optionally define the following methods: |
|
505 |
|
506 - A `writeReplace` method to allow a class to nominate a replacement object |
|
507 to be written to the stream |
|
508 |
|
509 (See [Section 2.5, "The writeReplace |
|
510 Method"](output.html#the-writereplace-method) for additional information.) |
|
511 |
|
512 - A `readResolve` method to allow a class to designate a replacement object |
|
513 for the object just read from the stream |
|
514 |
|
515 (See [Section 3.7, "The readResolve |
|
516 Method"](input.html#the-readresolve-method) for additional information.) |
|
517 |
|
518 ## 1.12 Serialization of Enum Constants |
|
519 |
|
520 Enum constants are serialized differently than ordinary serializable or |
|
521 externalizable objects. The serialized form of an enum constant consists solely |
|
522 of its name; field values of the constant are not present in the form. To |
|
523 serialize an enum constant, `ObjectOutputStream` writes the value returned by |
|
524 the enum constant's `name` method. To deserialize an enum constant, |
|
525 `ObjectInputStream` reads the constant name from the stream; the deserialized |
|
526 constant is then obtained by calling the `java.lang.Enum.valueOf` method, |
|
527 passing the constant's enum type along with the received constant name as |
|
528 arguments. Like other serializable or externalizable objects, enum constants |
|
529 can function as the targets of back references appearing subsequently in the |
|
530 serialization stream. |
|
531 |
|
532 The process by which enum constants are serialized cannot be customized: any |
|
533 class-specific `writeObject`, `readObject`, `readObjectNoData`, `writeReplace`, |
|
534 and `readResolve` methods defined by enum types are ignored during |
|
535 serialization and deserialization. Similarly, any `serialPersistentFields` or |
|
536 `serialVersionUID` field declarations are also ignored--all enum types have a |
|
537 fixed `serialVersionUID` of `0L`. Documenting serializable fields and data for |
|
538 enum types is unnecessary, since there is no variation in the type of data |
|
539 sent. |
|
540 |
|
541 ## 1.13 Protecting Sensitive Information |
|
542 |
|
543 When developing a class that provides controlled access to resources, care must |
|
544 be taken to protect sensitive information and functions. During |
|
545 deserialization, the private state of the object is restored. For example, a |
|
546 file descriptor contains a handle that provides access to an operating system |
|
547 resource. Being able to forge a file descriptor would allow some forms of |
|
548 illegal access, since restoring state is done from a stream. Therefore, the |
|
549 serializing runtime must take the conservative approach and not trust the |
|
550 stream to contain only valid representations of objects. To avoid compromising |
|
551 a class, the sensitive state of an object must not be restored from the stream, |
|
552 or it must be reverified by the class. Several techniques are available to |
|
553 protect sensitive data in classes. |
|
554 |
|
555 The easiest technique is to mark fields that contain sensitive data as *private |
|
556 transient*. Transient fields are not persistent and will not be saved by any |
|
557 persistence mechanism. Marking the field will prevent the state from appearing |
|
558 in the stream and from being restored during deserialization. Since writing and |
|
559 reading (of private fields) cannot be superseded outside of the class, the |
|
560 transient fields of the class are safe. |
|
561 |
|
562 Particularly sensitive classes should not be serialized at all. To accomplish |
|
563 this, the object should not implement either the `Serializable` or the |
|
564 `Externalizable` interface. |
|
565 |
|
566 Some classes may find it beneficial to allow writing and reading but |
|
567 specifically handle and revalidate the state as it is deserialized. The class |
|
568 should implement `writeObject` and `readObject` methods to save and restore |
|
569 only the appropriate state. If access should be denied, throwing a |
|
570 `NotSerializableException` will prevent further access. |
|
571 |
|
572 ------------------------------------------------------------------------------- |
|
573 |
|
574 *[Copyright](../../../legal/SMICopyright.html) © 2005, 2017, Oracle |
|
575 and/or its affiliates. All rights reserved.* |
|