Java Examples In A Nutshell (3rd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java Examples In A Nutshell (3rd Edition) [Electronic resources] - نسخه متنی

O'Reilly Media, Inc

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








10.4 Serialization and Class Versioning


Example 10-3 is that it includes a version number in the
serialization stream it writes. This is useful if the class evolves
in the future and needs to use a new serialization format. The
version number allows future versions of the class to recognize
serialized objects written by this version of the class.

For
Serializable objects that are not
Externalizable, the Serialization API handles
versioning itself. When an object is serialized, some information
about the object's class must obviously be
serialized with it, so that the correct class file can be loaded when
the object is deserialized. This information about the class is
represented by the java.io.ObjectStreamClass
class. It contains the fully qualified name of the class and a
version number for the class. The version number is very important
because an early version of a class may not be able to deserialize a
serialized instance created by a later version of the same class. The
version number for a class is a long value. By
default, the serialization mechanism creates a unique version number
by computing a hash of the name of the class, the name of its
superclass and any interfaces it implements, the name and type of its
fields, and the name and type of its nonprivate methods. Thus,
whenever you add a new method, change the name of a field, or make
even minor modifications to the API or implementation of a class, its
computed version number changes. When an object is serialized by one
version of a class, it can't be deserialized by a
version that has a different version number.

Thus,
when you make changes to a serializable class, even minor changes
that don't affect the serialization format, you
break serialization compatibility between versions. For example, our
SerialIntList class really ought to have a
set( ) method that sets the value of a specified
element of the list. But if you add this method, the new version of
the class can't deserialize objects serialized by
the old version. The way to prevent this problem is to explicitly
declare a version number for your class. You do this by giving the
class a constant field named serialVersionUID.

The value
of this field doesn't matter; it must simply be the
same for all versions of the class that have a compatible
serialization format. Since the SerialIntList
class shown in Example 10-2 doesn't
have a serialVersionUID field, its version number
was implicitly computed based on the API of the class. In order to
give an updated version of SerialIntList a version
number that matches the original version, use the
serialver command that comes with the Java SDK:

% serialver je3.serialization.SerialIntList
SerialIntList:static final long serialVersionUID = 2952055272471088220L;

If you run this program on the original version of the class, it
prints a field definition suitable for inclusion in the modified
version of the class. By including this constant field in the
modified class, you retain serialization compatibility between it and
the original version.


10.4.1 Advanced Versioning


Sometimes you make changes to a
class that alter the way the class stores its state. Imagine a
Rectangle class that represents the rectangle as
the coordinate of the upper-left corner, plus a width and a height.
Now suppose that the class is reimplemented so that it maintains
exactly the same public API, but the rectangle is now represented by
two points: the coordinates of the upper-left corner and the
lower-right corner. The internal private fields of the class have
changed, so it would appear that serialization compatibility between
the two implementations of the class is simply not possible.

One solution is to make the new version of the class
Externalizable, taking full control over the data
format, and using that to write the new implementation fields in the
old format. In Java 1.2 and later, however, the serialization
mechanism has been updated to allow the serialization format of
Serializable classes to be totally decoupled from
the fields used by a particular implementation or version of the
class. A class can now declare a private field named
serialPersistentFields that refers to an array of
java.io.ObjectStreamField objects. Each of these
objects defines a field name and a field type. These fields need not
have any relationship to the fields implemented by the class; they
are the fields of the serialized form of the class. By defining this
array of ObjectStreamField objects, the class is
specifying its serialization format. When a new version of the class
is defined, that new version must be able to save and restore its
state in the format defined by the
serialPersistentFields array.

The techniques for reading and writing
the serialization fields declared by the
serialPersistentFields array are beyond the scope
of this chapter. For more information, check the putFields(
)
and writeFields( ) methods of
ObjectOutputStream and the readFields(
)
method of ObjectInputStream. See also
the advanced serialization examples supplied as part of the Java SDK
documentation.

/ 285