jdk/src/java.base/share/specs/serialization/output.md
changeset 45534 f0b3d467215e
parent 45473 03c5450b6e4a
parent 45533 e6707cd51e28
child 45535 4b19310ae4ee
--- a/jdk/src/java.base/share/specs/serialization/output.md	Thu Jun 08 16:32:55 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,514 +0,0 @@
----
-# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-
-include-before: '[CONTENTS](index.html) | [PREV](serial-arch.html) | [NEXT](input.html)'
-include-after: '[CONTENTS](index.html) | [PREV](serial-arch.html) | [NEXT](input.html)'
-
-title: 'Java Object Serialization Specification: 2 - Object Output Classes'
----
-
--   [The ObjectOutputStream Class](#the-objectoutputstream-class)
--   [The ObjectOutputStream.PutField
-    Class](#the-objectoutputstream.putfield-class)
--   [The writeObject Method](#the-writeobject-method)
--   [The writeExternal Method](#the-writeexternal-method)
--   [The writeReplace Method](#the-writereplace-method)
--   [The useProtocolVersion Method](#the-useprotocolversion-method)
-
--------------------------------------------------------------------------------
-
-## 2.1 The ObjectOutputStream Class
-
-Class `ObjectOutputStream` implements object serialization. It maintains the
-state of the stream including the set of objects already serialized. Its
-methods control the traversal of objects to be serialized to save the specified
-objects and the objects to which they refer.
-
-```
-package java.io;
-
-public class ObjectOutputStream
-    extends OutputStream
-    implements ObjectOutput, ObjectStreamConstants
-{
-    public ObjectOutputStream(OutputStream out)
-        throws IOException;
-
-    public final void writeObject(Object obj)
-        throws IOException;
-
-    public void writeUnshared(Object obj)
-        throws IOException;
-
-    public void defaultWriteObject()
-        throws IOException, NotActiveException;
-
-    public PutField putFields()
-        throws IOException;
-
-    public writeFields()
-        throws IOException;
-
-    public void reset() throws IOException;
-
-    protected void annotateClass(Class cl) throws IOException;
-
-    protected void writeClassDescriptor(ObjectStreamClass desc)
-        throws IOException;
-
-    protected Object replaceObject(Object obj) throws IOException;
-
-    protected boolean enableReplaceObject(boolean enable)
-        throws SecurityException;
-
-    protected void writeStreamHeader() throws IOException;
-
-    public void write(int data) throws IOException;
-
-    public void write(byte b[]) throws IOException;
-
-    public void write(byte b[], int off, int len) throws IOException;
-
-    public void flush() throws IOException;
-
-    protected void drain() throws IOException;
-
-    public void close() throws IOException;
-
-    public void writeBoolean(boolean data) throws IOException;
-
-    public void writeByte(int data) throws IOException;
-
-    public void writeShort(int data) throws IOException;
-
-    public void writeChar(int data) throws IOException;
-
-    public void writeInt(int data) throws IOException;
-
-    public void writeLong(long data) throws IOException;
-
-    public void writeFloat(float data) throws IOException;
-
-    public void writeDouble(double data) throws IOException;
-
-    public void writeBytes(String data) throws IOException;
-
-    public void writeChars(String data) throws IOException;
-
-    public void writeUTF(String data) throws IOException;
-
-    // Inner class to provide access to serializable fields.
-    abstract static public class PutField
-    {
-        public void put(String name, boolean value)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, char data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, byte data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, short data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, int data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, long data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, float data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, double data)
-            throws IOException, IllegalArgumentException;
-
-        public void put(String name, Object data)
-            throws IOException, IllegalArgumentException;
-    }
-
-    public void useProtocolVersion(int version) throws IOException;
-
-    protected ObjectOutputStream()
-        throws IOException;
-
-     protected writeObjectOverride()
-        throws NotActiveException, IOException;
-}
-```
-
-The single-argument `ObjectOutputStream` constructor creates an
-`ObjectOutputStream` that serializes objects to the given `OutputStream`. The
-constructor calls `writeStreamHeader` to write a magic number and version to
-the stream that will be read and verified by a corresponding call to
-`readStreamHeader` in the single-argument `ObjectInputStream` constructor. If a
-security manager is installed, this constructor checks for the
-`"enableSubclassImplementation"` `SerializablePermission` when invoked directly
-or indirectly by the constructor of a subclass which overrides the `putFields`
-and/or `writeUnshared` methods.
-
-The `writeObject` method is used to serialize an object to the stream. An
-object is serialized as follows:
-
-1.  If a subclass is overriding the implementation, call the
-    `writeObjectOverride` method and return. Overriding the implementation is
-    described at the end of this section.
-
-2.  If there is data in the block-data buffer, the data is written to the
-    stream and the buffer is reset.
-
-3.  If the object is null, null is put in the stream and `writeObject` returns.
-
-4.  If the object has been previously replaced, as described in Step 8, write
-    the handle of the replacement to the stream and `writeObject` returns.
-
-5.  If the object has already been written to the stream, its handle is written
-    to the stream and `writeObject` returns.
-
-6.  If the object is a `Class`, the corresponding `ObjectStreamClass` is
-    written to the stream, a handle is assigned for the class, and
-    `writeObject` returns.
-
-7.  If the object is an `ObjectStreamClass`, a handle is assigned to the
-    object, after which it is written to the stream using one of the class
-    descriptor formats described in [Section 4.3, "Serialized
-    Form"](class.html#serialized-form). In versions 1.3 and later of the Java 2
-    SDK, Standard Edition, the `writeClassDescriptor` method is called to
-    output the `ObjectStreamClass` if it represents a class that is not a
-    dynamic proxy class, as determined by passing the associated `Class` object
-    to the `isProxyClass` method of `java.lang.reflect.Proxy`. Afterwards, an
-    annotation for the represented class is written: if the class is a dynamic
-    proxy class, then the `annotateProxyClass` method is called; otherwise, the
-    `annotateClass` method is called. The `writeObject` method then returns.
-
-8.  Process potential substitutions by the class of the object and/or by a
-    subclass of `ObjectInputStream`.
-
-    a.  If the class of an object is not an enum type and defines the
-        appropriate `writeReplace` method, the method is called. Optionally, it
-        can return a substitute object to be serialized.
-
-    b.  Then, if enabled by calling the `enableReplaceObject` method, the
-        `replaceObject` method is called to allow subclasses of
-        `ObjectOutputStream` to substitute for the object being serialized. If
-        the original object was replaced in the previous step, the
-        `replaceObject` method is called with the replacement object.
-
-    If the original object was replaced by either one or both steps above, the
-    mapping from the original object to the replacement is recorded for later
-    use in Step 4. Then, Steps 3 through 7 are repeated on the new object. 
-
-    If the replacement object is not one of the types covered by Steps 3
-    through 7, processing resumes using the replacement object at Step 10.
-
-9.  <a id="java-lang-string-encoding"></a>
-    If the object is a `java.lang.String,` the string is written as length
-    information followed by the contents of the string encoded in modified
-    UTF-8. For details, refer to [Section 6.2, "Stream
-    Elements"](protocol.html#stream-elements). A handle is assigned to the
-    string, and `writeObject` returns.
-
-10. If the object is an array, `writeObject` is called recursively to write the
-    `ObjectStreamClass` of the array. The handle for the array is assigned. It
-    is followed by the length of the array. Each element of the array is then
-    written to the stream, after which `writeObject` returns.
-
-11. If the object is an enum constant, the `ObjectStreamClass` for the enum
-    type of the constant is written by recursively calling `writeObject`. It
-    will appear in the stream only the first time it is referenced. A handle is
-    assigned for the enum constant. Next, the value returned by the `name`
-    method of the enum constant is written as a `String` object, as described
-    in step 9. Note that if the same name string has appeared previously in the
-    stream, a back reference to it will be written. The `writeObject` method
-    then returns.
-
-12. For regular objects, the `ObjectStreamClass` for the class of the object is
-    written by recursively calling `writeObject`. It will appear in the stream
-    only the first time it is referenced. A handle is assigned for the object.
-
-13. The contents of the object are written to the stream.
-
-    a.  If the object is serializable, the highest serializable class is
-        located. For that class, and each derived class, that class's fields
-        are written. If the class does not have a `writeObject` method, the
-        `defaultWriteObject` method is called to write the serializable fields
-        to the stream. If the class does have a `writeObject` method, it is
-        called. It may call `defaultWriteObject` or `putFields` and
-        `writeFields` to save the state of the object, and then it can write
-        other information to the stream.
-
-    b.  If the object is externalizable, the `writeExternal` method of the
-        object is called.
-
-    c.  If the object is neither serializable or externalizable, the
-        `NotSerializableException` is thrown.
-
-Exceptions may occur during the traversal or may occur in the underlying
-stream. For any subclass of `IOException`, the exception is written to the
-stream using the exception protocol and the stream state is discarded. If a
-second `IOException` is thrown while attempting to write the first exception
-into the stream, the stream is left in an unknown state and
-`StreamCorruptedException` is thrown from `writeObject`. For other exceptions,
-the stream is aborted and left in an unknown and unusable state.
-
-The `writeUnshared` method writes an "unshared" object to the
-`ObjectOutputStream`. This method is identical to `writeObject`, except that it
-always writes the given object as a new, unique object in the stream (as
-opposed to a back-reference pointing to a previously serialized instance).
-Specifically:
-
--   An object written via `writeUnshared` is always serialized in the same
-    manner as a newly appearing object (an object that has not been written to
-    the stream yet), regardless of whether or not the object has been written
-    previously.
-
--   If `writeObject` is used to write an object that has been previously
-    written with `writeUnshared`, the previous `writeUnshared` operation is
-    treated as if it were a write of a separate object. In other words,
-    `ObjectOutputStream` will never generate back-references to object data
-    written by calls to `writeUnshared`.
-
-While writing an object via `writeUnshared` does not in itself guarantee a
-unique reference to the object when it is deserialized, it allows a single
-object to be defined multiple times in a stream, so that multiple calls to the
-`ObjectInputStream.readUnshared` method (see [Section 3.1, "The
-ObjectInputStream Class"](input.html#the-objectinputstream-class)) by the
-receiver will not conflict. Note that the rules described above only apply to
-the base-level object written with `writeUnshared`, and not to any transitively
-referenced sub-objects in the object graph to be serialized.
-
-The `defaultWriteObject` method implements the default serialization mechanism
-for the current class. This method may be called only from a class's
-`writeObject` method. The method writes all of the serializable fields of the
-current class to the stream. If called from outside the `writeObject` method,
-the `NotActiveException` is thrown.
-
-The `putFields` method returns a `PutField` object the caller uses to set the
-values of the serializable fields in the stream. The fields may be set in any
-order. After all of the fields have been set, `writeFields` must be called to
-write the field values in the canonical order to the stream. If a field is not
-set, the default value appropriate for its type will be written to the stream.
-This method may only be called from within the `writeObject` method of a
-serializable class. It may not be called more than once or if
-`defaultWriteObject` has been called. Only after `writeFields` has been called
-can other data be written to the stream.
-
-The `reset` method resets the stream state to be the same as if it had just
-been constructed. `Reset` will discard the state of any objects already written
-to the stream. The current point in the stream is marked as reset, so the
-corresponding `ObjectInputStream` will reset at the same point. Objects
-previously written to the stream will not be remembered as already having been
-written to the stream. They will be written to the stream again. This is useful
-when the contents of an object or objects must be sent again. `Reset` may not
-be called while objects are being serialized. If called inappropriately, an
-`IOException` is thrown.
-
-Starting with the Java 2 SDK, Standard Edition, v1.3, the
-`writeClassDescriptor` method is called when an `ObjectStreamClass` needs to be
-serialized. `writeClassDescriptor` is responsible for writing a representation
-of the `ObjectStreamClass` to the serialization stream. Subclasses may override
-this method to customize the way in which class descriptors are written to the
-serialization stream. If this method is overridden, then the corresponding
-`readClassDescriptor` method in `ObjectInputStream` should also be overridden
-to reconstitute the class descriptor from its custom stream representation. By
-default, `writeClassDescriptor` writes class descriptors according to the
-format specified in [Section 6.4, "Grammar for the Stream
-Format"](protocol.html#grammar-for-the-stream-format). Note that this method
-will only be called if the `ObjectOutputStream` is not using the old
-serialization stream format (see [Section 6.3, "Stream Protocol
-Versions"](protocol.html#stream-protocol-versions)). If the serialization
-stream is using the old format (`ObjectStreamConstants.PROTOCOL_VERSION_1`),
-the class descriptor will be written internally in a manner that cannot be
-overridden or customized.
-
-The `annotateClass` method is called while a `Class` is being serialized, and
-after the class descriptor has been written to the stream. Subclasses may
-extend this method and write other information to the stream about the class.
-This information must be read by the `resolveClass` method in a corresponding
-`ObjectInputStream` subclass.
-
-An `ObjectOutputStream` subclass can implement the `replaceObject` method to
-monitor or replace objects during serialization. Replacing objects must be
-enabled explicitly by calling `enableReplaceObject` before calling
-`writeObject` with the first object to be replaced. Once enabled,
-`replaceObject` is called for each object just prior to serializing the object
-for the first time. Note that the `replaceObject` method is not called for
-objects of the specially handled classes, `Class` and `ObjectStreamClass`. An
-implementation of a subclass may return a substitute object that will be
-serialized instead of the original. The substitute object must be serializable.
-All references in the stream to the original object will be replaced by the
-substitute object.
-
-When objects are being replaced, the subclass must ensure that the substituted
-object is compatible with every field where the reference will be stored, or
-that a complementary substitution will be made during deserialization. Objects,
-whose type is not a subclass of the type of the field or array element, will
-later abort the deserialization by raising a `ClassCastException` and the
-reference will not be stored.
-
-The `enableReplaceObject` method can be called by trusted subclasses of
-`ObjectOutputStream` to enable the substitution of one object for another
-during serialization. Replacing objects is disabled until `enableReplaceObject`
-is called with a `true` value. It may thereafter be disabled by setting it to
-`false`. The previous setting is returned. The `enableReplaceObject` method
-checks that the stream requesting the replacement can be trusted. To ensure
-that the private state of objects is not unintentionally exposed, only trusted
-stream subclasses may use `replaceObject`. Trusted classes are those classes
-that belong to a security protection domain with permission to enable
-Serializable substitution.
-
-If the subclass of `ObjectOutputStream` is not considered part of the system
-domain, `SerializablePermission "enableSubstitution"` must be added to the
-security policy file. `AccessControlException` is thrown if the protection
-domain of the subclass of `ObjectInputStream` does not have permission to
-`"enableSubstitution"` by calling `enableReplaceObject`. See the document Java
-Security Architecture (JDK1.2) for additional information about the security
-model.
-
-The `writeStreamHeader` method writes the magic number and version to the
-stream. This information must be read by the `readStreamHeader` method of
-`ObjectInputStream`. Subclasses may need to implement this method to identify
-the stream's unique format.
-
-The `flush` method is used to empty any buffers being held by the stream and to
-forward the flush to the underlying stream. The `drain` method may be used by
-subclassers to empty only the `ObjectOutputStream`'s buffers without forcing
-the underlying stream to be flushed.
-
-All of the write methods for primitive types encode their values using a
-`DataOutputStream` to put them in the standard stream format. The bytes are
-buffered into block data records so they can be distinguished from the encoding
-of objects. This buffering allows primitive data to be skipped if necessary for
-class versioning. It also allows the stream to be parsed without invoking
-class-specific methods.
-
-To override the implementation of serialization, the subclass of
-`ObjectOutputStream` should call the protected no-arg `ObjectOutputStream`,
-constructor. There is a security check within the no-arg constructor for
-`SerializablePermission "enableSubclassImplementation"` to ensure that only
-trusted classes are allowed to override the default implementation. This
-constructor does not allocate any private data for `ObjectOutputStream` and
-sets a flag that indicates that the final `writeObject` method should invoke
-the `writeObjectOverride` method and return. All other `ObjectOutputStream`
-methods are not final and can be directly overridden by the subclass.
-
-## 2.2 The ObjectOutputStream.PutField Class
-
-Class `PutField` provides the API for setting values of the serializable fields
-for a class when the class does not use default serialization. Each method puts
-the specified named value into the stream. An `IllegalArgumentException` is
-thrown if `name` does not match the name of a serializable field for the class
-whose fields are being written, or if the type of the named field does not
-match the second parameter type of the specific `put` method invoked.
-
-## 2.3 The writeObject Method
-
-For serializable objects, the `writeObject` method allows a class to control
-the serialization of its own fields. Here is its signature:
-
-```
-private void writeObject(ObjectOutputStream stream)
-    throws IOException;
-```
-
-Each subclass of a serializable object may define its own `writeObject` method.
-If a class does not implement the method, the default serialization provided by
-`defaultWriteObject` will be used. When implemented, the class is only
-responsible for writing its own fields, not those of its supertypes or
-subtypes.
-
-The class's `writeObject` method, if implemented, is responsible for saving the
-state of the class. Either `ObjectOutputStream`'s `defaultWriteObject` or
-`writeFields` method must be called once (and only once) before writing any
-optional data that will be needed by the corresponding `readObject` method to
-restore the state of the object; even if no optional data is written,
-`defaultWriteObject` or `writeFields` must still be invoked once. If
-`defaultWriteObject` or `writeFields` is not invoked once prior to the writing
-of optional data (if any), then the behavior of instance deserialization is
-undefined in cases where the `ObjectInputStream` cannot resolve the class which
-defined the `writeObject` method in question.
-
-The responsibility for the format, structure, and versioning of the optional
-data lies completely with the class.
-
-## 2.4 The writeExternal Method
-
-Objects implementing `java.io.Externalizable` must implement the
-`writeExternal` method to save the entire state of the object. It must
-coordinate with its superclasses to save their state. All of the methods of
-`ObjectOutput` are available to save the object's primitive typed fields and
-object fields.
-
-```
-public void writeExternal(ObjectOutput stream)
-    throws IOException;
-```
-
-A new default format for writing Externalizable data has been introduced in JDK
-1.2. The new format specifies that primitive data will be written in block data
-mode by `writeExternal` methods. Additionally, a tag denoting the end of the
-External object is appended to the stream after the `writeExternal` method
-returns. The benefits of this format change are discussed in [Section 3.6, "The
-readExternal Method"](input.html#the-readexternal-method). Compatibility issues
-caused by this change are discussed in [Section 2.6, "The useProtocolVersion
-Method"](#the-useprotocolversion-method).
-
-## 2.5 The writeReplace Method
-
-For Serializable and Externalizable classes, the `writeReplace` method allows a
-class of an object to nominate its own replacement in the stream before the
-object is written. By implementing the `writeReplace` method, a class can
-directly control the types and instances of its own instances being serialized.
-
-The method is defined as follows:
-
-```
-ANY-ACCESS-MODIFIER Object writeReplace()
-             throws ObjectStreamException;
-```
-
-The `writeReplace` method is called when `ObjectOutputStream` is preparing to
-write the object to the stream. The `ObjectOutputStream` checks whether the
-class defines the `writeReplace` method. If the method is defined, the
-`writeReplace` method is called to allow the object to designate its
-replacement in the stream. The object returned should be either of the same
-type as the object passed in or an object that when read and resolved will
-result in an object of a type that is compatible with all references to the
-object. If it is not, a `ClassCastException` will occur when the type mismatch
-is discovered.
-
-## 2.6 The useProtocolVersion Method
-
-Due to a stream protocol change that was not backwards compatible, a mechanism
-has been added to enable the current Virtual Machine to write a serialization
-stream that is readable by a previous release. Of course, the problems that are
-corrected by the new stream format will exist when using the backwards
-compatible protocol.
-
-Stream protocol versions are discussed in [Section 6.3, "Stream Protocol
-Versions"](protocol.html#stream-protocol-versions).
-
--------------------------------------------------------------------------------
-
-*[Copyright](../../../legal/SMICopyright.html) &copy; 2005, 2017, Oracle
-and/or its affiliates. All rights reserved.*