< prev index next >

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

Print this page
@@ -215,10 +215,12 @@
   * 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.
+  * Value objects cannot be `java.io.Externalizable` because value objects are
+  * immutable and `Externalizable.readExternal` is unable to modify the fields of the value.
   *
   * <p>Enum constants are deserialized differently than ordinary serializable or
   * externalizable objects.  The serialized form of an enum constant consists
   * solely of its name; field values of the constant are not transmitted.  To
   * deserialize an enum constant, ObjectInputStream reads the constant name from

@@ -240,10 +242,15 @@
   * 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.
   *
+  * <p>Value objects are deserialized differently than ordinary serializable objects or records.
+  * See <a href="{@docRoot}/../specs/serialization/serial-arch.html#serialization-of-value-objects">
+  * <cite>Java Object Serialization Specification,</cite> Section 1.14,
+  * "Serialization of Value Objects"</a> for additional information.
+  *
   * @spec serialization/index.html Java Object Serialization Specification
   * @author      Mike Warres
   * @author      Roger Riggs
   * @see java.io.DataInput
   * @see java.io.ObjectOutputStream

@@ -2249,11 +2256,12 @@
          } catch (Exception ex) {
              throw new InvalidClassException(desc.forClass().getName(),
                                              "unable to create instance", ex);
          }
  
-         passHandle = handles.assign(unshared ? unsharedMarker : obj);
+         // Assign the handle and initially set to null or the unsharedMarker
+         passHandle = handles.assign(unshared ? unsharedMarker : null);
          ClassNotFoundException resolveEx = desc.getResolveException();
          if (resolveEx != null) {
              handles.markException(passHandle, resolveEx);
          }
  

@@ -2262,12 +2270,28 @@
              assert obj == null;
              obj = readRecord(desc);
              if (!unshared)
                  handles.setObject(passHandle, obj);
          } else if (desc.isExternalizable()) {
+             if (desc.isValue()) {
+                 throw new NotSerializableException("Externalizable not valid for value class "
+                         + cl.getName());
+             }
+             if (!unshared)
+                 handles.setObject(passHandle, obj);
              readExternalData((Externalizable) obj, desc);
+         } else if (desc.isValue()) {
+             // For value objects, read the fields and finish the buffer before publishing the ref
+             assert obj != null : "obj == null: " + desc;
+             readSerialData(obj, desc);
+             obj = desc.finishValue(obj);
+             if (!unshared)
+                 handles.setObject(passHandle, obj);
          } else {
+             // For all other objects, publish the ref and then read the data
+             if (!unshared)
+                 handles.setObject(passHandle, obj);
              readSerialData(obj, desc);
          }
  
          handles.finish(passHandle);
  
< prev index next >