objectoutputstream.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,976 行 · 第 1/5 页

JAVA
1,976
字号
/* * @(#)ObjectOutputStream.java	1.112 02/01/03 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program 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 program 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 at /legal/license.txt).    *    * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package java.io;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.Arrays;import sun.misc.SoftCache;import sun.misc.CVM;/** * An ObjectOutputStream writes primitive data types and graphs of Java objects * to an OutputStream.  The objects can be read (reconstituted) using an * ObjectInputStream.  Persistent storage of objects can be accomplished by * using a file for the stream.  If the stream is a network socket stream, the * objects can be reconsituted on another host or in another process. * * <p>Only objects that support the java.io.Serializable interface can be * written to streams.  The class of each serializable object is encoded * including the class name and signature of the class, the values of the * object's fields and arrays, and the closure of any other objects referenced * from the initial objects. * * <p>The method writeObject is used to write an object to the stream.  Any * object, including Strings and arrays, is written with writeObject. Multiple * objects or primitives can be written to the stream.  The objects must be * read back from the corresponding ObjectInputstream with the same types and * in the same order as they were written. * * <p>Primitive data types can also be written to the stream using the * appropriate methods from DataOutput. Strings can also be written using the * writeUTF method. * * <p>The default serialization mechanism for an object writes the class of the * object, the class signature, and the values of all non-transient and * non-static fields.  References to other objects (except in transient or * static fields) cause those objects to be written also. Multiple references * to a single object are encoded using a reference sharing mechanism so that * graphs of objects can be restored to the same shape as when the original was * written. * * <p>For example to write an object that can be read by the example in * ObjectInputStream: * <br> * <pre> *	FileOutputStream fos = new FileOutputStream("t.tmp"); *	ObjectOutputStream oos = new ObjectOutputStream(fos); * *	oos.writeInt(12345); *	oos.writeObject("Today"); *	oos.writeObject(new Date()); * *	oos.close(); * </pre> * * <p>Classes that require special handling during the serialization and * deserialization process must implement special methods with these exact * signatures: * <br> * <pre> * private void readObject(java.io.ObjectInputStream stream) *     throws IOException, ClassNotFoundException; * private void writeObject(java.io.ObjectOutputStream stream) *     throws IOException * </pre> *  * <p>The writeObject method is responsible for writing the state of the object * for its particular class so that the corresponding readObject method can * restore it.  The method does not need to concern itself with the state * belonging to the object's superclasses or subclasses.  State is saved by * writing the individual fields to the ObjectOutputStream using the * writeObject method or by using the methods for primitive data types * supported by DataOutput. * * <p>Serialization does not write out the fields of any object that does not * implement the java.io.Serializable interface.  Subclasses of Objects that * are not serializable can be serializable. In this case the non-serializable * class must have a no-arg constructor to allow its fields to be initialized. * In this case it is the responsibility of the subclass to save and restore * the state of the non-serializable class. It is frequently the case that the * fields of that class are accessible (public, package, or protected) or that * there are get and set methods that can be used to restore the state. * * <p>Serialization of an object can be prevented by implementing writeObject * and readObject methods that throw the NotSerializableException. * The exception will be caught by the ObjectOutputStream and abort the * serialization process. * * <p>Implementing the Externalizable interface allows the object to assume * complete control over the contents and format of the object's serialized * form.  The methods of the Externalizable interface, writeExternal and * readExternal, are called to save and restore the objects state.  When * implemented by a class they can write and read their own state using all of * the methods of ObjectOutput and ObjectInput.  It is the responsibility of * the objects to handle any versioning that occurs. * * <p>Primitive data, excluding serializable fields and externalizable data, is * written to the ObjectOutputStream in block-data records. A block data record * is composed of a header and data. The block data header consists of a marker * and the number of bytes to follow the header.  Consecutive primitive data * writes are merged into one block-data record.  The blocking factor used for * a block-data record will be 1024 bytes.  Each block-data record will be * filled up to 1024 bytes, or be written whenever there is a termination of * block-data mode.  Calls to the ObjectOutputStream methods writeObject, * defaultWriteObject and writeFields initially terminate any existing * block-data record. * * @author      Mike Warres * @author	Roger Riggs * @version     1.105, 08/09/01 * @see java.io.DataOutput * @see java.io.ObjectInputStream * @see java.io.Serializable * @see java.io.Externalizable * @see <a href="../../../guide/serialization/spec/output.doc.html"> Object Serialization Specification, Section 2, Object Output Classes</a> * @since       JDK1.1 */public class ObjectOutputStream    extends OutputStream implements ObjectOutput, ObjectStreamConstants{    /** cache of subclass security audit results */    private static final SoftCache subclassAudits = new SoftCache(5);    /** filter stream for handling block data conversion */    private final BlockDataOutputStream bout;    /** obj -> wire handle map */    private final HandleTable handles;    /** obj -> replacement obj map */    private final ReplaceTable subs;    /** stream protocol version */    private int protocol = PROTOCOL_VERSION_2;    /** recursion depth */    private int depth;    /** buffer for writing primitive field values */    private byte[] primVals;    /** if true, invoke writeObjectOverride() instead of writeObject() */    private final boolean enableOverride;    /** if true, invoke replaceObject() */    private boolean enableReplace;    // values below valid only during upcalls to writeObject()/writeExternal()    /** object currently being serialized */    private Object curObj;    /** descriptor for current class (null if in writeExternal()) */    private ObjectStreamClass curDesc;    /** current PutField object */    private PutFieldImpl curPut;    /**     * Creates an ObjectOutputStream that writes to the specified OutputStream.     * This constructor writes the serialization stream header to the     * underlying stream; callers may wish to flush the stream immediately to     * ensure that constructors for receiving ObjectInputStreams will not block     * when reading the header.     *     * <p>If a security manager is installed, this constructor will check for     * the "enableSubclassImplementation" SerializablePermission when invoked     * directly or indirectly by the constructor of a subclass which overrides     * the ObjectOutputStream.putFields or ObjectOutputStream.writeUnshared     * methods.     *     * @param	out output stream to write to     * @throws	IOException if an I/O error occurs while writing stream header     * @throws	SecurityException if untrusted subclass illegally overrides     * 		security-sensitive methods     * @throws	NullPointerException if <code>out</code> is <code>null</code>     * @see	ObjectOutputStream#ObjectOutputStream()     * @see	ObjectOutputStream#putFields()     * @see	ObjectInputStream#ObjectInputStream(InputStream)     */    public ObjectOutputStream(OutputStream out) throws IOException {	verifySubclass();	bout = new BlockDataOutputStream(out);	handles = new HandleTable(10, (float) 3.00);	subs = new ReplaceTable(10, (float) 3.00);	enableOverride = false;	writeStreamHeader();	bout.setBlockDataMode(true);    }    /**     * Provide a way for subclasses that are completely reimplementing     * ObjectOutputStream to not have to allocate private data just used by     * this implementation of ObjectOutputStream.     *     * <p>If there is a security manager installed, this method first calls the     * security manager's <code>checkPermission</code> method with a     * <code>SerializablePermission("enableSubclassImplementation")</code>     * permission to ensure it's ok to enable subclassing.     *     * @exception IOException   Thrown if not called by a subclass.     *      * @throws SecurityException     *    if a security manager exists and its      *    <code>checkPermission</code> method denies     *    enabling subclassing.     *     * @see SecurityManager#checkPermission     * @see java.io.SerializablePermission     */    protected ObjectOutputStream() throws IOException, SecurityException {	SecurityManager sm = System.getSecurityManager();	if (sm != null) {	    sm.checkPermission(ObjectStreamConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);	}	bout = null;	handles = null;	subs = null;	enableOverride = true;    }    /**     * Specify stream protocol version to use when writing the stream.     *     * <p>This routine provides a hook to enable the current version of     * Serialization to write in a format that is backwards compatible to a     * previous version of the stream format.     *     * <p>Every effort will be made to avoid introducing additional     * backwards incompatibilities; however, sometimes there is no     * other alternative.     *     * @param	version use ProtocolVersion from java.io.ObjectStreamConstants.     * @throws	IllegalStateException if called after any objects     * 		have been serialized.     * @throws	IllegalArgumentException if invalid version is passed in.     * @throws	IOException if I/O errors occur     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1     * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_2     * @since	1.2     */    public void useProtocolVersion(int version) throws IOException {	if (handles.size() != 0) {	    // TODO: implement better check for pristine stream?	    throw new IllegalStateException("stream non-empty");	}	switch (version) {	    case PROTOCOL_VERSION_1:	    case PROTOCOL_VERSION_2:		protocol = version;		break;			    default:		throw new IllegalArgumentException(		    "unknown version: " + version);	}    }    /**     * Write the specified object to the ObjectOutputStream.  The class of the     * object, the signature of the class, and the values of the non-transient     * and non-static fields of the class and all of its supertypes are     * written.  Default serialization for a class can be overridden using the     * writeObject and the readObject methods.  Objects referenced by this     * object are written transitively so that a complete equivalent graph of     * objects can be reconstructed by an ObjectInputStream.     *     * <p>Exceptions are thrown for problems with the OutputStream and for     * classes that should not be serialized.  All exceptions are fatal to the     * OutputStream, which is left in an indeterminate state, and it is up to     * the caller to ignore or recover the stream state.     *     * @throws	InvalidClassException Something is wrong with a class used by     *		serialization.     * @throws	NotSerializableException Some object to be serialized does not     *		implement the java.io.Serializable interface.     * @throws	IOException Any exception thrown by the underlying     * 		OutputStream.     */    public final void writeObject(Object obj) throws IOException {	if (enableOverride) {	    writeObjectOverride(obj);	    return;	}	try {	    writeObject0(obj, false);	} catch (IOException ex) {	    if (depth == 0) {		writeFatalException(ex);	    }	    throw ex;	}    }    /**     * Method used by subclasses to override the default writeObject method.     * This method is called by trusted subclasses of ObjectInputStream     * that constructed ObjectInputStream using the     * protected no-arg constructor. The subclass is expected to provide     * an override method with the modifier "final".     *     * @param obj object to be written to the underlying stream     * @throws IOException if there are I/O errors while writing to the     * underlying stream     * @see #ObjectOutputStream()     * @see #writeObject(Object)     * @since 1.2     */    protected void writeObjectOverride(Object obj) throws IOException {    }    /**     * 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:     * <ul>     *   <li>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.     *     *   <li>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.     * </ul>     * 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 readUnshared 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.     *     * <p>ObjectOutputStream subclasses which override this method can only be     * constructed in security contexts possessing the     * "enableSubclassImplementation" SerializablePermission; any attempt to     * instantiate such a subclass without this permission will cause a     * SecurityException to be thrown.     *     * @param   obj object to write to stream     * @throws  NotSerializableException if an object in the graph to be     *          serialized does not implement the Serializable interface     * @throws  InvalidClassException if a problem exists with the class of an     *          object to be serialized     * @throws  IOException if an I/O error occurs during serialization     *     */    public void writeUnshared(Object obj) throws IOException {        try {            writeObject0(obj, true);        } catch (IOException ex) {            if (depth == 0) {                writeFatalException(ex);            }            throw ex;        }    }    /**     * Write the non-static and non-transient fields of the current class     * to this stream.  This may only be called from the writeObject method     * of the class being serialized. It will throw the NotActiveException     * if it is called otherwise.     *     * @throws IOException if I/O errors occur while writing to the underlying     * <code>OutputStream</code>     */    public void defaultWriteObject() throws IOException {	if (curObj == null || curDesc == null) {	    throw new NotActiveException("not in call to writeObject");	}	bout.setBlockDataMode(false);	defaultWriteFields(curObj, curDesc);	bout.setBlockDataMode(true);    }    

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?