8256679: Update serialization javadoc once JOSS changes for records are complete

Reviewed-by: chegar, rriggs
This commit is contained in:
Julia Boes 2020-12-07 09:30:52 +00:00
parent 7620124ee9
commit d05401d886
5 changed files with 24 additions and 50 deletions

@ -223,39 +223,14 @@ import sun.security.action.GetIntegerAction;
* Similarly, any serialPersistentFields or serialVersionUID field declarations
* are also ignored--all enum types have a fixed serialVersionUID of 0L.
*
* @implSpec
* <a id="record-serialization"></a>
* Records are serialized differently than ordinary serializable or externalizable
* objects. The serialized form of a record object is a sequence of values derived
* from the record components. The stream format of a record object is the same as
* that of an ordinary object in the stream. During deserialization, if the local
* class equivalent of the specified stream class descriptor is a record class,
* then first the stream fields are read and reconstructed to serve as the record's
* component values; and second, a record object is created by invoking the
* record's <i>canonical</i> constructor with the component values as arguments (or the
* default value for component's type if a component value is absent from the
* stream).
* Like other serializable or externalizable objects, record objects can function
* as the target of back references appearing subsequently in the serialization
* stream. However, a cycle in the graph where the record object is referred to,
* either directly or transitively, by one of its components, is not preserved.
* The record components are deserialized prior to the invocation of the record
* constructor, hence this limitation (see
* <a href="{@docRoot}/../specs/serialization/serial-arch.html#cyclic-references">
* <cite>Java Object Serialization Specification,</cite>
* Section 1.14, "Circular References"</a> for additional information).
* The process by which record objects are serialized or externalized cannot be
* customized; any class-specific writeObject, readObject, readObjectNoData,
* writeExternal, and readExternal methods defined by record classes are
* ignored during serialization and deserialization. However, a substitute object
* to be serialized or a designate replacement may be specified, by the
* writeReplace and readResolve methods, respectively. Any
* serialPersistentFields field declaration is ignored. Documenting serializable
* fields and data for record classes is unnecessary, since there is no variation
* in the serial form, other than whether a substitute or replacement object is
* used. The serialVersionUID of a record class is 0L unless explicitly
* declared. The requirement for matching serialVersionUID values is waived for
* record classes.
* <p>Records are serialized differently than ordinary serializable or externalizable
* objects. During deserialization the record's canonical constructor is invoked
* to construct the record object. Certain serialization-related methods, such
* as readObject and writeObject, are ignored for serializable records. See
* <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-records">
* <cite>Java Object Serialization Specification,</cite> Section 1.13,
* "Serialization of Records"</a> for additional information.
*
* @author Mike Warres
* @author Roger Riggs

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, 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
@ -150,8 +150,7 @@ import sun.reflect.misc.ReflectUtil;
* defaultWriteObject and writeFields initially terminate any existing
* block-data record.
*
* @implSpec
* Records are serialized differently than ordinary serializable or externalizable
* <p>Records are serialized differently than ordinary serializable or externalizable
* objects, see <a href="ObjectInputStream.html#record-serialization">record serialization</a>.
*
* @author Mike Warres
@ -1483,7 +1482,6 @@ public class ObjectOutputStream
}
/** Writes the record component values for the given record object. */
@SuppressWarnings("preview")
private void writeRecordData(Object obj, ObjectStreamClass desc)
throws IOException
{

@ -490,11 +490,6 @@ public class ObjectStreamClass implements Serializable {
}
}
@SuppressWarnings("preview")
private static boolean isRecord(Class<?> cls) {
return cls.isRecord();
}
/**
* Creates local class descriptor representing given class.
*/
@ -503,7 +498,7 @@ public class ObjectStreamClass implements Serializable {
name = cl.getName();
isProxy = Proxy.isProxyClass(cl);
isEnum = Enum.class.isAssignableFrom(cl);
isRecord = isRecord(cl);
isRecord = cl.isRecord();
serializable = Serializable.class.isAssignableFrom(cl);
externalizable = Externalizable.class.isAssignableFrom(cl);
@ -718,7 +713,7 @@ public class ObjectStreamClass implements Serializable {
}
if (model.serializable == osc.serializable &&
!cl.isArray() && !isRecord(cl) &&
!cl.isArray() && !cl.isRecord() &&
suid != osc.getSerialVersionUID()) {
throw new InvalidClassException(osc.name,
"local class incompatible: " +
@ -780,7 +775,7 @@ public class ObjectStreamClass implements Serializable {
deserializeEx = localDesc.deserializeEx;
}
domains = localDesc.domains;
assert isRecord(cl) ? localDesc.cons == null : true;
assert cl.isRecord() ? localDesc.cons == null : true;
cons = localDesc.cons;
}
@ -1590,9 +1585,8 @@ public class ObjectStreamClass implements Serializable {
* the not found ( which should never happen for correctly generated record
* classes ).
*/
@SuppressWarnings("preview")
private static MethodHandle canonicalRecordCtr(Class<?> cls) {
assert isRecord(cls) : "Expected record, got: " + cls;
assert cls.isRecord() : "Expected record, got: " + cls;
PrivilegedAction<MethodHandle> pa = () -> {
Class<?>[] paramTypes = Arrays.stream(cls.getRecordComponents())
.map(RecordComponent::getType)
@ -1743,7 +1737,7 @@ public class ObjectStreamClass implements Serializable {
return NO_FIELDS;
ObjectStreamField[] fields;
if (isRecord(cl)) {
if (cl.isRecord()) {
fields = getDefaultSerialFields(cl);
Arrays.sort(fields);
} else if (!Externalizable.class.isAssignableFrom(cl) &&
@ -2663,7 +2657,6 @@ public class ObjectStreamClass implements Serializable {
* and return
* {@code Object}
*/
@SuppressWarnings("preview")
static MethodHandle deserializationCtr(ObjectStreamClass desc) {
// check the cached value 1st
MethodHandle mh = desc.deserializationCtr;

@ -139,6 +139,12 @@ package java.io;
* serialization and deserialization. Any declarations of the special
* handling methods discussed above are ignored for enum types.<p>
*
* Record classes can implement {@code Serializable} and receive treatment defined
* by the <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-records">
* <cite>Java Object Serialization Specification,</cite> Section 1.13,
* "Serialization of Records"</a>. Any declarations of the special
* handling methods discussed above are ignored for record types.<p>
*
* The serialization runtime associates with each serializable class a version
* number, called a serialVersionUID, which is used during deserialization to
* verify that the sender and receiver of a serialized object have loaded

@ -74,8 +74,10 @@ package java.lang;
* deserialization the record's canonical constructor is invoked to construct
* the record object. Certain serialization-related methods, such as readObject
* and writeObject, are ignored for serializable records. More information about
* serializable records can be found in
* <a href="{@docRoot}/java.base/java/io/ObjectInputStream.html#record-serialization">record serialization</a>.
* serializable records can be found in the
* <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-records">
* <cite>Java Object Serialization Specification,</cite> Section 1.13,
* "Serialization of Records"</a>.
*
* @jls 8.10 Record Types
* @since 16