< prev index next >

src/java.base/share/classes/java/io/ObjectOutputStream.java

Print this page

   1 /*
   2  * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

 143  * enum constants are serialized cannot be customized; any class-specific
 144  * writeObject and writeReplace methods defined by enum types are ignored
 145  * during serialization.  Similarly, any serialPersistentFields or
 146  * serialVersionUID field declarations are also ignored--all enum types have a
 147  * fixed serialVersionUID of 0L.
 148  *
 149  * <p>Primitive data, excluding serializable fields and externalizable data, is
 150  * written to the ObjectOutputStream in block-data records. A block data record
 151  * is composed of a header and data. The block data header consists of a marker
 152  * and the number of bytes to follow the header.  Consecutive primitive data
 153  * writes are merged into one block-data record.  The blocking factor used for
 154  * a block-data record will be 1024 bytes.  Each block-data record will be
 155  * filled up to 1024 bytes, or be written whenever there is a termination of
 156  * block-data mode.  Calls to the ObjectOutputStream methods writeObject,
 157  * defaultWriteObject and writeFields initially terminate any existing
 158  * block-data record.
 159  *
 160  * <p>Records are serialized differently than ordinary serializable or externalizable
 161  * objects, see <a href="ObjectInputStream.html#record-serialization">record serialization</a>.
 162  *











 163  * @spec serialization/index.html Java Object Serialization Specification
 164  * @author      Mike Warres
 165  * @author      Roger Riggs
 166  * @see java.io.DataOutput
 167  * @see java.io.ObjectInputStream
 168  * @see java.io.Serializable
 169  * @see java.io.Externalizable
 170  * @see <a href="{@docRoot}/../specs/serialization/output.html">
 171  *      <cite>Java Object Serialization Specification,</cite> Section 2, "Object Output Classes"</a>
 172  * @since       1.1
 173  */
 174 public class ObjectOutputStream
 175     extends OutputStream implements ObjectOutput, ObjectStreamConstants
 176 {
 177     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 178 
 179     /** filter stream for handling block data conversion */
 180     private final BlockDataOutputStream bout;
 181     /** obj -> wire handle map */
 182     private final HandleTable handles;

 294             default:
 295                 throw new IllegalArgumentException(
 296                     "unknown version: " + version);
 297         }
 298     }
 299 
 300     /**
 301      * Write the specified object to the ObjectOutputStream.  The class of the
 302      * object, the signature of the class, and the values of the non-transient
 303      * and non-static fields of the class and all of its supertypes are
 304      * written.  Default serialization for a class can be overridden using the
 305      * writeObject and the readObject methods.  Objects referenced by this
 306      * object are written transitively so that a complete equivalent graph of
 307      * objects can be reconstructed by an ObjectInputStream.
 308      *
 309      * <p>Exceptions are thrown for problems with the OutputStream and for
 310      * classes that should not be serialized.  All exceptions are fatal to the
 311      * OutputStream, which is left in an indeterminate state, and it is up to
 312      * the caller to ignore or recover the stream state.
 313      *












 314      * @throws  InvalidClassException Something is wrong with a class used by
 315      *          serialization.
 316      * @throws  NotSerializableException Some object to be serialized does not
 317      *          implement the java.io.Serializable interface.
 318      * @throws  IOException Any exception thrown by the underlying
 319      *          OutputStream.
 320      */
 321     public final void writeObject(Object obj) throws IOException {
 322         if (enableOverride) {
 323             writeObjectOverride(obj);
 324             return;
 325         }
 326         try {
 327             writeObject0(obj, false);
 328         } catch (IOException ex) {
 329             if (depth == 0) {
 330                 writeFatalException(ex);
 331             }
 332             throw ex;
 333         }

1297     private void writeOrdinaryObject(Object obj,
1298                                      ObjectStreamClass desc,
1299                                      boolean unshared)
1300         throws IOException
1301     {
1302         if (extendedDebugInfo) {
1303             debugInfoStack.push(
1304                 (depth == 1 ? "root " : "") + "object (class \"" +
1305                 obj.getClass().getName() + "\", " + obj.toString() + ")");
1306         }
1307         try {
1308             desc.checkSerialize();
1309 
1310             bout.writeByte(TC_OBJECT);
1311             writeClassDesc(desc, false);
1312             handles.assign(unshared ? null : obj);
1313 
1314             if (desc.isRecord()) {
1315                 writeRecordData(obj, desc);
1316             } else if (desc.isExternalizable() && !desc.isProxy()) {

1317                 writeExternalData((Externalizable) obj);
1318             } else {
1319                 writeSerialData(obj, desc);
1320             }
1321         } finally {
1322             if (extendedDebugInfo) {
1323                 debugInfoStack.pop();
1324             }
1325         }
1326     }
1327 
1328     /**
1329      * Writes externalizable data of given object by invoking its
1330      * writeExternal() method.
1331      */
1332     private void writeExternalData(Externalizable obj) throws IOException {
1333         PutFieldImpl oldPut = curPut;
1334         curPut = null;
1335 
1336         if (extendedDebugInfo) {

   1 /*
   2  * Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

 143  * enum constants are serialized cannot be customized; any class-specific
 144  * writeObject and writeReplace methods defined by enum types are ignored
 145  * during serialization.  Similarly, any serialPersistentFields or
 146  * serialVersionUID field declarations are also ignored--all enum types have a
 147  * fixed serialVersionUID of 0L.
 148  *
 149  * <p>Primitive data, excluding serializable fields and externalizable data, is
 150  * written to the ObjectOutputStream in block-data records. A block data record
 151  * is composed of a header and data. The block data header consists of a marker
 152  * and the number of bytes to follow the header.  Consecutive primitive data
 153  * writes are merged into one block-data record.  The blocking factor used for
 154  * a block-data record will be 1024 bytes.  Each block-data record will be
 155  * filled up to 1024 bytes, or be written whenever there is a termination of
 156  * block-data mode.  Calls to the ObjectOutputStream methods writeObject,
 157  * defaultWriteObject and writeFields initially terminate any existing
 158  * block-data record.
 159  *
 160  * <p>Records are serialized differently than ordinary serializable or externalizable
 161  * objects, see <a href="ObjectInputStream.html#record-serialization">record serialization</a>.
 162  *
 163  * <div class="preview-block">
 164  *      <div class="preview-comment">
 165  *          <p>{@linkplain Class#isValue Value classes} that are not records cannot be
 166  *          serialized directly. To serialize an instance of a value class, the
 167  *          <a href="{@docRoot}/../specs/serialization/output.html#the-writereplace-method">
 168  *          {@code writeReplace}</a> method can provide a proxy object instead. That
 169  *          object can then be serialized, and used to reconstruct the expected value
 170  *          class instance at deserialization time.
 171  *      </div>
 172  * </div>
 173  *
 174  * @spec serialization/index.html Java Object Serialization Specification
 175  * @author      Mike Warres
 176  * @author      Roger Riggs
 177  * @see java.io.DataOutput
 178  * @see java.io.ObjectInputStream
 179  * @see java.io.Serializable
 180  * @see java.io.Externalizable
 181  * @see <a href="{@docRoot}/../specs/serialization/output.html">
 182  *      <cite>Java Object Serialization Specification,</cite> Section 2, "Object Output Classes"</a>
 183  * @since       1.1
 184  */
 185 public class ObjectOutputStream
 186     extends OutputStream implements ObjectOutput, ObjectStreamConstants
 187 {
 188     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 189 
 190     /** filter stream for handling block data conversion */
 191     private final BlockDataOutputStream bout;
 192     /** obj -> wire handle map */
 193     private final HandleTable handles;

 305             default:
 306                 throw new IllegalArgumentException(
 307                     "unknown version: " + version);
 308         }
 309     }
 310 
 311     /**
 312      * Write the specified object to the ObjectOutputStream.  The class of the
 313      * object, the signature of the class, and the values of the non-transient
 314      * and non-static fields of the class and all of its supertypes are
 315      * written.  Default serialization for a class can be overridden using the
 316      * writeObject and the readObject methods.  Objects referenced by this
 317      * object are written transitively so that a complete equivalent graph of
 318      * objects can be reconstructed by an ObjectInputStream.
 319      *
 320      * <p>Exceptions are thrown for problems with the OutputStream and for
 321      * classes that should not be serialized.  All exceptions are fatal to the
 322      * OutputStream, which is left in an indeterminate state, and it is up to
 323      * the caller to ignore or recover the stream state.
 324      *
 325      * <div class="preview-block">
 326      *      <div class="preview-comment">
 327      *          <p>An object that instantiates a concrete
 328      *          {@linkplain Class#isValue value class}, or that extends a
 329      *          Serializable abstract value class that declares instance fields,
 330      *          can only be serialized if it is a record, or it implements
 331      *          {@code writeReplace}, or it is a boxed primitive value.
 332      *          Otherwise, {@code writeObject} throws an
 333      *          {@code InvalidClassException}.
 334      *      </div>
 335      * </div>
 336      *
 337      * @throws  InvalidClassException Something is wrong with a class used by
 338      *          serialization.
 339      * @throws  NotSerializableException Some object to be serialized does not
 340      *          implement the java.io.Serializable interface.
 341      * @throws  IOException Any exception thrown by the underlying
 342      *          OutputStream.
 343      */
 344     public final void writeObject(Object obj) throws IOException {
 345         if (enableOverride) {
 346             writeObjectOverride(obj);
 347             return;
 348         }
 349         try {
 350             writeObject0(obj, false);
 351         } catch (IOException ex) {
 352             if (depth == 0) {
 353                 writeFatalException(ex);
 354             }
 355             throw ex;
 356         }

1320     private void writeOrdinaryObject(Object obj,
1321                                      ObjectStreamClass desc,
1322                                      boolean unshared)
1323         throws IOException
1324     {
1325         if (extendedDebugInfo) {
1326             debugInfoStack.push(
1327                 (depth == 1 ? "root " : "") + "object (class \"" +
1328                 obj.getClass().getName() + "\", " + obj.toString() + ")");
1329         }
1330         try {
1331             desc.checkSerialize();
1332 
1333             bout.writeByte(TC_OBJECT);
1334             writeClassDesc(desc, false);
1335             handles.assign(unshared ? null : obj);
1336 
1337             if (desc.isRecord()) {
1338                 writeRecordData(obj, desc);
1339             } else if (desc.isExternalizable() && !desc.isProxy()) {
1340                 assert !desc.requiresDeserializer() : "Should be caught in checkSerialize";
1341                 writeExternalData((Externalizable) obj);
1342             } else {
1343                 writeSerialData(obj, desc);
1344             }
1345         } finally {
1346             if (extendedDebugInfo) {
1347                 debugInfoStack.pop();
1348             }
1349         }
1350     }
1351 
1352     /**
1353      * Writes externalizable data of given object by invoking its
1354      * writeExternal() method.
1355      */
1356     private void writeExternalData(Externalizable obj) throws IOException {
1357         PutFieldImpl oldPut = curPut;
1358         curPut = null;
1359 
1360         if (extendedDebugInfo) {
< prev index next >