< prev index next > src/java.base/share/classes/java/io/ObjectOutputStream.java
Print this page
/*
! * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Alibaba Group Holding Limited. 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
/*
! * Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Alibaba Group Holding Limited. 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
* block-data record.
*
* <p>Records are serialized differently than ordinary serializable or externalizable
* objects, see <a href="ObjectInputStream.html#record-serialization">record serialization</a>.
*
+ * <div class="preview-block">
+ * <div class="preview-comment">
+ * <p>{@linkplain Class#isValue Value classes} that are not records cannot be
+ * serialized directly. To serialize an instance of a value class, the
+ * <a href="{@docRoot}/../specs/serialization/output.html#the-writereplace-method">
+ * {@code writeReplace}</a> method can provide a proxy object instead. That
+ * object can then be serialized, and used to reconstruct the expected value
+ * class instance at deserialization time.
+ * </div>
+ * </div>
+ *
* @spec serialization/index.html Java Object Serialization Specification
* @author Mike Warres
* @author Roger Riggs
* @see java.io.DataOutput
* @see java.io.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.
*
+ * <div class="preview-block">
+ * <div class="preview-comment">
+ * <p>An object that instantiates or extends a Serializable
+ * {@linkplain Class#isValue value class} can only be serialized if
+ * it is a record, or it implements {@code writeReplace}, or it is
+ * a boxed primitive value. Otherwise, {@code writeObject} throws an
+ * {@code InvalidClassException}.
+ * </div>
+ * </div>
+ *
* @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
handles.assign(unshared ? null : obj);
if (desc.isRecord()) {
writeRecordData(obj, desc);
} else if (desc.isExternalizable() && !desc.isProxy()) {
+ if (desc.isValue())
+ throw new InvalidClassException("Externalizable not valid for value class "
+ + desc.forClass().getName());
writeExternalData((Externalizable) obj);
} else {
writeSerialData(obj, desc);
}
} finally {
/** Writes the record component values for the given record object. */
private void writeRecordData(Object obj, ObjectStreamClass desc)
throws IOException
{
assert obj.getClass().isRecord();
! ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
! if (slots.length != 1) {
throw new InvalidClassException(
! "expected a single record slot length, but found: " + slots.length);
}
defaultWriteFields(obj, desc); // #### seems unnecessary to use the accessors
}
/** Writes the record component values for the given record object. */
private void writeRecordData(Object obj, ObjectStreamClass desc)
throws IOException
{
assert obj.getClass().isRecord();
! List<ObjectStreamClass.ClassDataSlot> slots = desc.getClassDataLayout();
! if (slots.size() != 1) {
throw new InvalidClassException(
! "expected a single record slot length, but found: " + slots.size());
}
defaultWriteFields(obj, desc); // #### seems unnecessary to use the accessors
}
* superclass to subclass.
*/
private void writeSerialData(Object obj, ObjectStreamClass desc)
throws IOException
{
! ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
! for (int i = 0; i < slots.length; i++) {
! ObjectStreamClass slotDesc = slots[i].desc;
if (slotDesc.hasWriteObjectMethod()) {
PutFieldImpl oldPut = curPut;
curPut = null;
SerialCallbackContext oldContext = curContext;
* superclass to subclass.
*/
private void writeSerialData(Object obj, ObjectStreamClass desc)
throws IOException
{
! List<ObjectStreamClass.ClassDataSlot> slots = desc.getClassDataLayout();
! for (int i = 0; i < slots.size(); i++) {
! ObjectStreamClass slotDesc = slots.get(i).desc;
if (slotDesc.hasWriteObjectMethod()) {
PutFieldImpl oldPut = curPut;
curPut = null;
SerialCallbackContext oldContext = curContext;
< prev index next >