The following are enhancements to serialization prior to Java™ SE Development Kit 6 (JDK). For enhancements in the current release, see Serialization Changes and Enhancements in Java SE Development Kit 6.
Enum.valueOf
method is called with that
class and the received constant name in order to obtain the enum
constant to return.ClassNotFoundException
thrown by the
ObjectInputStream.readClassDescriptor
method would be
reflected to the top-level caller of
ObjectInputStream.readObject
as a
StreamCorruptedException
with an empty cause. It is
now reflected to the top-level caller as an
InvalidClassException
with the original
ClassNotFoundException
as the cause.ObjectStreamClass.lookup
method could deadlock if
called from within the static initializer of the class represented
by the method's Class
argument. Deadlock should no
longer occur in this case.Serializable
interface has
been expanded to more completely specify the role and usage of
serialVersionUID
s, and to emphasize the need to
specify explicit serialVersionUID
s for serializable
classes.These APIs can be used to more efficiently read contained array objects in a secure fashion; for more information, see section A.6 of the Java Object Serialization Specification, "Guarding Unshared Deserialized Objects".
Also beginning with J2SE 1.4.0, ObjectInputStream's public one-argument constructor requires the "enableSubclassImplementation" SerializablePermission when invoked (either directly or indirectly) by a subclass which overrides ObjectInputStream.readFields or ObjectInputStream.readUnshared.
These changes will not affect the great majority of applications. However, it will affect any ObjectInputStream/ObjectOutputStream subclasses which override the putFields or readFields methods without also overriding the rest of the serialization infrastructure.
private void readObjectNoData() throws ObjectStreamException;The readObjectNoData() method is analogous to the class-defined readObject() method, except that (if defined) it is called in cases where the class descriptor for a superclass of the object being deserialized (and hence the object data described by that class descriptor) is not present in the serialization stream. More formally: If object O of class C is being deserialized, and S is a superclass of C in the VM which is deserializing O, then S.readObjectNoData() is invoked by ObjectInputStream during the deserialization of O if and only if the following conditions are true:
See the class description in the API specification of ObjectInputStream for more information.
java.io.UTFDataFormatException
being
thrown. In 1.3, the serialization protocol has been enhanced to
allow strings longer than 64K to be serialized. Note that if a 1.2
(or earlier) JVM attempts to read a long string written from a
1.3-compatible JVM, the 1.2 (or earlier) JVM will receive a
java.io.StreamCorruptedException
.java.lang.ClassNotFoundException
is thrown instead of
a generic one so that more information about the failure is
available. Also, deserialization exception reporting now includes
maintaining the name of the original class that could not be found
instead of reporting a higher-level class that was being
deserialized. For example, if (in an RMI call) the stub class
can be found but the remote interface class cannot, the
serialization mechanism will now report correctly that the
interface class was the class that could not be found instead of
erroneously reporting that the stub class could not be found.java.io.ObjectOutputStream.writeClassDescriptor
,java.io.ObjectInputStream.readClassDescriptor
(since
1.3)writeClassDescriptor
and
readClassDescriptor
methods have been added to provide
a means of customizing the serialized representation of
java.io.ObjectStreamClass
class descriptors.
writeClassDescriptor
is called when an instance of
java.io.ObjectStreamClass
needs to be serialized, and
is responsible for writing the ObjectStreamClass
to
the serialization stream. Conversely,
readClassDescriptor
is called when the
ObjectInputStream
expects an
ObjectStreamClass
instance as the next item in the
serialization stream. By overriding these methods, subclasses of
ObjectOutputStream
and ObjectInputStream
can transmit class descriptors in an application-specific format.
For more information, refer to sections 2.1 and 3.1 of the Java
Object Serialization Specification.java.io.ObjectOutputStream.annotateProxyClass
,java.io.ObjectInputStream.resolveProxyClass
(since
1.3)ObjectOutputStream.annotateClass
and
ObjectInputStream.resolveClass
, except that they apply
to dynamic proxy classes (see
java.lang.reflect.Proxy
), as opposed to non-proxy
classes. Subclasses of ObjectOutputStream
may override
annotateProxyClass
to store custom data in the stream
along with descriptors for dynamic proxy classes.
ObjectInputStream
subclasses may then override
resolveProxyClass
to make use of the custom data in
selecting a local class to associate with the given proxy class
descriptor. For details, see section 4 of the Java Object
Serialization Specification.@serial
,
@serialField
, and @serialData
(since
1.2)@serial
,
@serialField
, and @serialData
have been
added to provide a way to document the serialized form of a class.
Javadoc generates a serialization specification based on the
contents of these tags. For details, refer to section 1.6 of the
Java Object Serialization Specification.java.io.Externalizable
interface if the classes for
those objects were not available. In 1.2, a new protocol version
was added which addressed this deficiency. For backwards
compatibility, ObjectOutputStream
and
ObjectInputStream
can read and write serialization
streams written in either protocol; the protocol version used can
be selected by calling the
ObjectOutputStream.useProtocolVersion
method. For
details and a discussion of compatibility issues, see section 6.3
of the Java Object Serialization Specification.writeReplace
and
readResolve
methods (since 1.2)writeReplace
and
readResolve
methods which allow instances of the given
classes to nominate replacements for themselves during
serialization and deserialization. The required signatures of these
methods, along with further details, are described in sections 2.5
and 3.6 of the Java Object Serialization Specification.java.io.ObjectOutputStream.writeObjectOverride
,
java.io.ObjectInputStream.readObjectOverride
(since
1.2)ObjectOutputStream
and
ObjectInputStream
can implement a custom serialization
protocol by overriding the writeObjectOverride
and
readObjectOverride
methods. Note that these methods
will only be called if the
ObjectOutputStream/ObjectInputStream
subclasses
possess the permission
java.io.SerializablePermission("enableSubclassImplementation")
,
and call the no-argument constructors of
ObjectOutputStream/ObjectInputStream
. See sections 2.1
and 3.1 of the Java Object Serialization Specification for
more information.ObjectOutputStream
and
ObjectInputStream
may override inherited methods to
obtain "hooks" into certain aspects of the serialization process.
Since 1.2, object serialization uses the 1.2 security model to
verify that subclasses possess adequate permissions to override
certain hooks. The permissions
java.io.SerializablePermission("enableSubclassImplementation
")
and
java.io.SerializablePermission("enableSubstitution
")
govern whether or not the methods
ObjectOutputStream.writeObjectOverride
,
ObjectOutputStream.replaceObject
,
ObjectInputStream.readObjectOverride
, and
ObjectInputStream.resolveObject
will be called during
the course of serialization. See sections 2.1 and 3.1 of the
Java Object Serialization Specifications for more
information.serialPersistentFields
, serializable classes can
dictate which fields will be written when instances of the class
(or subclasses) are serialized. This feature also enables classes
to "define" serializable fields which do not correspond directly to
actual fields in the class. Used in conjunction with the
serializable fields API (described below), this capability allows
fields to be added or removed from a class without altering the
serialized representation of the class. See sections 1.5 and 1.7 of
the Java Object Serialization Specification for
details.writeObject
/readObject
methods to explicitly set and retrieve serializable field values by
name and type. This API is particularly useful for classes that
need to maintain backwards compatibility with older class versions;
in some cases, the older version of the class may have defined a
set of serializable fields that cannot be mapped directly to the
fields of the current class. In this case, newer versions of the
class can define custom writeObject
and
readObject
methods that convert the internal state of
a given instance of the (new) class into the "old" serialized form,
and vice versa. For more information, see section 1.7 of the
Java Object Serialization Specification.