jdk/src/java.base/share/specs/serialization/class.md
changeset 45529 bee5c64ff49f
parent 45528 1e8c2f062ad3
child 45530 3c98842fddf7
equal deleted inserted replaced
45528:1e8c2f062ad3 45529:bee5c64ff49f
     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](input.html) | [NEXT](version.html)'
       
    24 include-after: '[CONTENTS](index.html) | [PREV](input.html) | [NEXT](version.html)'
       
    25 
       
    26 title: 'Java Object Serialization Specification: 4 - Class Descriptors'
       
    27 ---
       
    28 
       
    29 -   [The ObjectStreamClass Class](#the-objectstreamclass-class)
       
    30 -   [Dynamic Proxy Class Descriptors](#dynamic-proxy-class-descriptors)
       
    31 -   [Serialized Form](#serialized-form)
       
    32 -   [The ObjectStreamField Class](#the-objectstreamfield-class)
       
    33 -   [Inspecting Serializable Classes](#inspecting-serializable-classes)
       
    34 -   [Stream Unique Identifiers](#stream-unique-identifiers)
       
    35 
       
    36 -------------------------------------------------------------------------------
       
    37 
       
    38 ## 4.1 The ObjectStreamClass Class
       
    39 
       
    40 The `ObjectStreamClass` provides information about classes that are saved in a
       
    41 Serialization stream. The descriptor provides the fully-qualified name of the
       
    42 class and its serialization version UID. A `SerialVersionUID` identifies the
       
    43 unique original class version for which this class is capable of writing
       
    44 streams and from which it can read.
       
    45 
       
    46 ```
       
    47 package java.io;
       
    48 
       
    49 public class ObjectStreamClass
       
    50 {
       
    51     public static ObjectStreamClass lookup(Class cl);
       
    52 
       
    53         public static ObjectStreamClass lookupAny(Class cl);
       
    54 
       
    55     public String getName();
       
    56 
       
    57     public Class forClass();
       
    58 
       
    59     public ObjectStreamField[] getFields();
       
    60 
       
    61     public long getSerialVersionUID();
       
    62 
       
    63     public String toString();
       
    64 }
       
    65 ```
       
    66 
       
    67 The `lookup` method returns the `ObjectStreamClass` descriptor for the
       
    68 specified class in the virtual machine. If the class has defined
       
    69 `serialVersionUID` it is retrieved from the class. If the `serialVersionUID` is
       
    70 not defined by the class, it is computed from the definition of the class in
       
    71 the virtual machine. *I*f the specified class is not serializable or
       
    72 externalizable, *null* is returned.
       
    73 
       
    74 The `lookupAny` method behaves like the `lookup` method, except that it returns
       
    75 the descriptor for any class, regardless of whether it implements
       
    76 `Serializable`. The `serialVersionUID` of a class that does not implement
       
    77 `Serializable` is *0L.*
       
    78 
       
    79 The `getName` method returns the name of the class, in the same format that is
       
    80 used by the `Class.getName` method.
       
    81 
       
    82 The `forClass` method returns the `Class` in the local virtual machine if one
       
    83 was found by `ObjectInputStream.resolveClass` method. Otherwise, it returns
       
    84 *null*.
       
    85 
       
    86 The `getFields` method returns an array of `ObjectStreamField` objects that
       
    87 represent the serializable fields of this class.
       
    88 
       
    89 The `getSerialVersionUID` method returns the `serialVersionUID` of this class.
       
    90 Refer to [Section 4.6, "Stream Unique
       
    91 Identifiers"](#stream-unique-identifiers). If not specified by the class, the
       
    92 value returned is a hash computed from the class's name, interfaces, methods,
       
    93 and fields using the Secure Hash Algorithm (SHA) as defined by the National
       
    94 Institute of Standards.
       
    95 
       
    96 The `toString` method returns a printable representation of the class
       
    97 descriptor including the name of the class and the `serialVersionUID`.
       
    98 
       
    99 ## 4.2 Dynamic Proxy Class Descriptors
       
   100 
       
   101 ObjectStreamClass descriptors are also used to provide information about
       
   102 dynamic proxy classes (e.g., classes obtained via calls to the getProxyClass
       
   103 method of java.lang.reflect.Proxy) saved in a serialization stream. A dynamic
       
   104 proxy class itself has no serializable fields and a serialVersionUID of 0L. In
       
   105 other words, when the Class object for a dynamic proxy class is passed to the
       
   106 static lookup method of ObjectStreamClass, the returned ObjectStreamClass
       
   107 instance will have the following properties:
       
   108 
       
   109 -   Invoking its getSerialVersionUID method will return 0L.
       
   110 -   Invoking its getFields method will return an array of length zero.
       
   111 -   Invoking its getField method with any String argument will return null.
       
   112 
       
   113 ## 4.3 Serialized Form
       
   114 
       
   115 The serialized form of an ObjectStreamClass instance depends on whether or not
       
   116 the Class object it represents is serializable, externalizable, or a dynamic
       
   117 proxy class.
       
   118 
       
   119 When an `ObjectStreamClass` instance that does not represent a dynamic proxy
       
   120 class is written to the stream, it writes the class name and
       
   121 `serialVersionUID`, flags, and the number of fields. Depending on the class,
       
   122 additional information may be written:
       
   123 
       
   124 -   For non-serializable classes, the number of fields is always zero. Neither
       
   125     the `SC_SERIALIZABLE` nor the `SC_EXTERNALIZABLE` flag bits are set.
       
   126 
       
   127 -   For serializable classes, the `SC_SERIALIZABLE` flag is set, the number of
       
   128     fields counts the number of serializable fields and is followed by a
       
   129     descriptor for each serializable field. The descriptors are written in
       
   130     canonical order. The descriptors for primitive typed fields are written
       
   131     first sorted by field name followed by descriptors for the object typed
       
   132     fields sorted by field name. The names are sorted using `String.compareTo`.
       
   133     For details of the format, refer to [Section 6.4, "Grammar for the Stream
       
   134     Format"](protocol.html#grammar-for-the-stream-format).
       
   135 
       
   136 -   For externalizable classes, flags includes the `SC_EXTERNALIZABLE` flag,
       
   137     and the number of fields is always zero.
       
   138 
       
   139 -   For enum types, flags includes the `SC_ENUM` flag, and the number of fields
       
   140     is always zero.
       
   141 
       
   142 When an ObjectOutputStream serializes the ObjectStreamClass descriptor for a
       
   143 dynamic proxy class, as determined by passing its Class object to the
       
   144 isProxyClass method of java.lang.reflect.Proxy, it writes the number of
       
   145 interfaces that the dynamic proxy class implements, followed by the interface
       
   146 names. Interfaces are listed in the order that they are returned by invoking
       
   147 the getInterfaces method on the Class object of the dynamic proxy class.
       
   148 
       
   149 The serialized representations of ObjectStreamClass descriptors for dynamic
       
   150 proxy classes and non-dynamic proxy classes are differentiated through the use
       
   151 of different typecodes (`TC_PROXYCLASSDESC` and `TC_CLASSDESC`, respectively);
       
   152 for a more detailed specification of the grammar, see [Section 6.4, "Grammar
       
   153 for the Stream Format"](protocol.html#grammar-for-the-stream-format).
       
   154 
       
   155 ## 4.4 The ObjectStreamField Class
       
   156 
       
   157 An `ObjectStreamField` represents a serializable field of a serializable class.
       
   158 The serializable fields of a class can be retrieved from the
       
   159 `ObjectStreamClass`.
       
   160 
       
   161 The special static serializable field, `serialPersistentFields`, is an array of
       
   162 `ObjectStreamField` components that is used to override the default
       
   163 serializable fields.
       
   164 
       
   165 ```
       
   166 package java.io;
       
   167 
       
   168 public class ObjectStreamField implements Comparable {
       
   169 
       
   170     public ObjectStreamField(String fieldName,
       
   171                              Class fieldType);
       
   172 
       
   173     public ObjectStreamField(String fieldName,
       
   174                              Class fieldType,
       
   175                              boolean unshared);
       
   176 
       
   177     public String getName();
       
   178 
       
   179     public Class getType();
       
   180 
       
   181     public String getTypeString();
       
   182 
       
   183     public char getTypeCode();
       
   184 
       
   185     public boolean isPrimitive();
       
   186 
       
   187     public boolean isUnshared();
       
   188 
       
   189     public int getOffset();
       
   190 
       
   191     protected void setOffset(int offset);
       
   192 
       
   193     public int compareTo(Object obj);
       
   194 
       
   195     public String toString();
       
   196 }
       
   197 ```
       
   198 
       
   199 `ObjectStreamField` objects are used to specify the serializable fields of a
       
   200 class or to describe the fields present in a stream. Its constructors accept
       
   201 arguments describing the field to represent: a string specifying the name of
       
   202 the field, a `Class` object specifying the type of the field, and a `boolean`
       
   203 flag (implicitly `false` for the two-argument constructor) indicating whether
       
   204 or not values of the represented field should be read and written as "unshared"
       
   205 objects if default serialization/deserialization is in use (see the
       
   206 descriptions of the `ObjectInputStream.readUnshared` and
       
   207 `ObjectOutputStream.writeUnshared` methods in [Section 3.1, "The
       
   208 ObjectInputStream Class"](input.html#the-objectinputstream-class) and [Section
       
   209 2.1, "The ObjectOutputStream Class"](output.html#the-objectoutputstream-class),
       
   210 respectively).
       
   211 
       
   212 The `getName` method returns the name of the serializable field.
       
   213 
       
   214 The `getType` method returns the type of the field.
       
   215 
       
   216 The `getTypeString` method returns the type signature of the field.
       
   217 
       
   218 The `getTypeCode` method returns a character encoding of the field type ('`B`'
       
   219 for `byte`, '`C`' for `char`, '`D`' for `double`, '`F`' for `float`, '`I`' for
       
   220 `int`, '`J`' for `long`, '`L`' for non-array object types, '`S`' for `short`,
       
   221 '`Z`' for `boolean`, and '`[`' for arrays).
       
   222 
       
   223 The `isPrimitive` method returns `true` if the field is of primitive type, or
       
   224 `false` otherwise.
       
   225 
       
   226 The `isUnshared` method returns `true` if values of the field should be written
       
   227 as "unshared" objects, or `false` otherwise.
       
   228 
       
   229 The `getOffset` method returns the offset of the field's value within instance
       
   230 data of the class defining the field.
       
   231 
       
   232 The `setOffset` method allows `ObjectStreamField` subclasses to modify the
       
   233 offset value returned by the `getOffset` method.
       
   234 
       
   235 The `compareTo` method compares `ObjectStreamFields` for use in sorting.
       
   236 Primitive fields are ranked as "smaller" than non-primitive fields; fields
       
   237 otherwise equal are ranked alphabetically.
       
   238 
       
   239 The `toString` method returns a printable representation with name and type.
       
   240 
       
   241 ## 4.5 Inspecting Serializable Classes
       
   242 
       
   243 The program *serialver* can be used to find out if a class is serializable and
       
   244 to get its `serialVersionUID`. 
       
   245 
       
   246 When invoked on the command line with one or more class names, serialver prints
       
   247 the `serialVersionUID` for each class in a form suitable for copying into an
       
   248 evolving class. When invoked with no arguments, it prints a usage line.
       
   249 
       
   250 ## 4.6 Stream Unique Identifiers
       
   251 
       
   252 Each versioned class must identify the original class version for which it is
       
   253 capable of writing streams and from which it can read. For example, a versioned
       
   254 class must declare:
       
   255 
       
   256 ```
       
   257 private static final long serialVersionUID = 3487495895819393L;
       
   258 ```
       
   259 
       
   260 The stream-unique identifier is a 64-bit hash of the class name, interface
       
   261 class names, methods, and fields. The value must be declared in all versions of
       
   262 a class except the first. It may be declared in the original class but is not
       
   263 required. The value is fixed for all compatible classes. If the SUID is not
       
   264 declared for a class, the value defaults to the hash for that class. The
       
   265 `serialVersionUID` for dynamic proxy classes and enum types always have the
       
   266 value *0L*. Array classes cannot declare an explicit `serialVersionUID`, so
       
   267 they always have the default computed value, but the requirement for matching
       
   268 `serialVersionUID` values is waived for array classes.
       
   269 
       
   270 **Note:** It is strongly recommended that all serializable classes explicitly
       
   271 declare `serialVersionUID` values, since the default `serialVersionUID`
       
   272 computation is highly sensitive to class details that may vary depending on
       
   273 compiler implementations, and can thus result in unexpected `serialVersionUID`
       
   274 conflicts during deserialization, causing deserialization to fail.
       
   275 
       
   276 The initial version of an `Externalizable` class must output a stream data
       
   277 format that is extensible in the future. The initial version of the method
       
   278 `readExternal` has to be able to read the output format of all future versions
       
   279 of the method `writeExternal`.
       
   280 
       
   281 The `serialVersionUID` is computed using the signature of a stream of bytes
       
   282 that reflect the class definition. The National Institute of Standards and
       
   283 Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a signature
       
   284 for the stream. The first two 32-bit quantities are used to form a 64-bit hash.
       
   285 A `java.lang.DataOutputStream` is used to convert primitive data types to a
       
   286 sequence of bytes. The values input to the stream are defined by the Java
       
   287 Virtual Machine (VM) specification for classes. Class modifiers may include the
       
   288 `ACC_PUBLIC`, `ACC_FINAL`, `ACC_INTERFACE`, and `ACC_ABSTRACT` flags; other
       
   289 flags are ignored and do not affect `serialVersionUID` computation. Similarly,
       
   290 for field modifiers, only the `ACC_PUBLIC`, `ACC_PRIVATE`, `ACC_PROTECTED`,
       
   291 `ACC_STATIC`, `ACC_FINAL`, `ACC_VOLATILE`, and `ACC_TRANSIENT` flags are used
       
   292 when computing `serialVersionUID` values. For constructor and method modifiers,
       
   293 only the `ACC_PUBLIC`, `ACC_PRIVATE`, `ACC_PROTECTED`, `ACC_STATIC`,
       
   294 `ACC_FINAL`, `ACC_SYNCHRONIZED`, `ACC_NATIVE`, `ACC_ABSTRACT` and `ACC_STRICT`
       
   295 flags are used. Names and descriptors are written in the format used by the
       
   296 `java.io.DataOutputStream.writeUTF` method.
       
   297 
       
   298 The sequence of items in the stream is as follows:
       
   299 
       
   300 1.  The class name.
       
   301 
       
   302 2.  The class modifiers written as a 32-bit integer.
       
   303 
       
   304 3.  The name of each interface sorted by name.
       
   305 
       
   306 4.  For each field of the class sorted by field name (except `private static`
       
   307     and `private transient` fields:
       
   308 
       
   309     a.  The name of the field.
       
   310 
       
   311     b.  The modifiers of the field written as a 32-bit integer.
       
   312 
       
   313     c.  The descriptor of the field.
       
   314 
       
   315 5.  If a class initializer exists, write out the following:
       
   316 
       
   317     a.  The name of the method, `<clinit>`.
       
   318 
       
   319     b.  The modifier of the method, `java.lang.reflect.Modifier.STATIC`,
       
   320         written as a 32-bit integer.
       
   321 
       
   322     c.  The descriptor of the method, `()V`.
       
   323 
       
   324 6.  For each non-`private` constructor sorted by method name and signature:
       
   325 
       
   326     a.  The name of the method, `<init>`.
       
   327 
       
   328     b.  The modifiers of the method written as a 32-bit integer.
       
   329 
       
   330     c.  The descriptor of the method.
       
   331 
       
   332 7.  For each non-`private` method sorted by method name and signature:
       
   333 
       
   334     a.  The name of the method.
       
   335 
       
   336     b.  The modifiers of the method written as a 32-bit integer.
       
   337 
       
   338     c.  The descriptor of the method.
       
   339 
       
   340 8.  The SHA-1 algorithm is executed on the stream of bytes produced by
       
   341     `DataOutputStream` and produces five 32-bit values `sha[0..4]`.
       
   342 
       
   343 9.  The hash value is assembled from the first and second 32-bit values of the
       
   344     SHA-1 message digest. If the result of the message digest, the five 32-bit
       
   345     words `H0 H1 H2 H3 H4`, is in an array of five `int` values named `sha`,
       
   346     the hash value would be computed as follows:
       
   347 
       
   348 ```
       
   349       long hash = ((sha[0] >>> 24) & 0xFF) |
       
   350                   ((sha[0] >>> 16) & 0xFF) << 8 |
       
   351                   ((sha[0] >>> 8) & 0xFF) << 16 |
       
   352                   ((sha[0] >>> 0) & 0xFF) << 24 |
       
   353                   ((sha[1] >>> 24) & 0xFF) << 32 |
       
   354                   ((sha[1] >>> 16) & 0xFF) << 40 |
       
   355                   ((sha[1] >>> 8) & 0xFF) << 48 |
       
   356                   ((sha[1] >>> 0) & 0xFF) << 56;
       
   357 ```
       
   358 
       
   359 -------------------------------------------------------------------------------
       
   360 
       
   361 *[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
       
   362 and/or its affiliates. All rights reserved.*