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 + -
显示快捷键?