annotate src/java.base/share/specs/serialization/serial-arch.md @ 17166:ef9954f6896b

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