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

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

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

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

O'Reilly Media, Inc

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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










10.1 Simple Serialization


Despite the power and importance of
serialization, it is performed using a simple API that forms part of
the java.io package: an object is serialized by
the writeObject( ) method of the
ObjectOutputStream class and deserialized by the
readObject( ) method of the
ObjectInputStream class. These classes are byte
streams like the various other streams we saw in Chapter 3. They implement the
ObjectOutput and ObjectInput
interfaces, respectively, and these interfaces extend the
DataOutput and DataInput
interfaces. This means that ObjectOutputStream
defines the same methods as DataOutputStream for
writing primitive values, while ObjectInputStream
defines the same methods as DataInputStream for
reading primitive values. The methods we're
interested in here, however, are writeObject( )
and readObject( ), which write and read objects.

Only objects that implement the
java.io.Serializable interface may be serialized.
Serializable is a marker interface; it
doesn't define any methods that need to be
implemented. Nevertheless, for security reasons, some classes
don't want their private state to be exposed by the
serialization mechanism. Therefore, a class must explicitly declare
itself to be serializable by implementing this interface.

An object is
serialized by passing it to the writeObject( )
method of an ObjectOutputStream. This writes out
the values of all of its fields, including private fields and fields
inherited from superclasses. The values of primitive fields are
simply written to the stream as they would be with a
DataOutputStream. When a field in an object refers
to another object, an array, or a string, however, the
writeObject( ) method is invoked recursively to
serialize that object as well. If that object (or an array element)
refers to another object, writeObject( ) is again
invoked recursively. Thus, a single call to writeObject(
)
may result in an entire object graph being serialized.
When two or more objects each refer to the other, the serialization
algorithm is careful to output each object only once;
writeObject( ) can't enter
infinite recursion.

Deserializing an object simply follows
the reverse of this process. An object is read from a stream of data
by calling the readObject( ) method of an
ObjectInputStream. This creates a copy of the
object in the state it was in when serialized. If the object refers
to other objects, they are recursively deserialized as well.

Example 10-1 demonstrates the basics of serialization. The
example defines generic methods that can store and retrieve any
serializable object's state to and from a file. It
also includes an interesting deepclone( ) method
that uses serialization to copy an object graph. The example includes
a Serializable inner class and a test class that
demonstrates the methods at work.

Example 10-1. Serializer.java

package je3.serialization;
import java.io.*;
/**
* This class defines utility routines that use Java serialization.
**/
public class Serializer {
/**
* Serialize the object o (and any Serializable objects it refers to) and
* store its serialized state in File f.
**/
static void store(Serializable o, File f) throws IOException {
ObjectOutputStream out = // The class for serialization
new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(o); // This method serializes an object graph
out.close( );
}
/**
* Deserialize the contents of File f and return the resulting object
**/
static Object load(File f) throws IOException, ClassNotFoundException {
ObjectInputStream in = // The class for deserialization
new ObjectInputStream(new FileInputStream(f));
return in.readObject( ); // This method deserializes an object graph
}
/**
* Use object serialization to make a "deep clone" of the object o.
* This method serializes o and all objects it refers to, and then
* deserializes that graph of objects, which means that everything is
* copied. This differs from the clone( ) method of an object, which is
* usually implemented to produce a "shallow" clone that copies references
* to other objects, instead of copying all referenced objects.
**/
static Object deepclone(final Serializable o)
throws IOException, ClassNotFoundException
{
// Create a connected pair of "piped" streams.
// We'll write bytes to one, and then from the other one.
final PipedOutputStream pipeout = new PipedOutputStream( );
PipedInputStream pipein = new PipedInputStream(pipeout);
// Now define an independent thread to serialize the object and write
// its bytes to the PipedOutputStream
Thread writer = new Thread( ) {
public void run( ) {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(pipeout);
out.writeObject(o);
}
catch(IOException e) { }
finally {
try { out.close( ); } catch (Exception e) { }
}
}
};
writer.start( ); // Make the thread start serializing and writing
// Meanwhile, in this thread, read and deserialize from the piped
// input stream. The resulting object is a deep clone of the original.
ObjectInputStream in = new ObjectInputStream(pipein);
return in.readObject( );
}
/**
* This is a simple serializable data structure that we use below for
* testing the methods above
**/
public static class DataStructure implements Serializable {
String message;
int[ ] data;
DataStructure other;
public String toString( ) {
String s = message;
for(int i = 0; i < data.length; i++)
s += " " + data[i];
if (other != null) s += "\n\t" + other.toString( );
return s;
}
}
/** This class defines a main( ) method for testing */
public static class Test {
public static void main(String[ ] args)
throws IOException, ClassNotFoundException
{
// Create a simple object graph
DataStructure ds = new DataStructure( );
ds.message = "hello world";
ds.data = new int[ ] { 1, 2, 3, 4 };
ds.other = new DataStructure( );
ds.other.message = "nested structure";
ds.other.data = new int[ ] { 9, 8, 7 };
// Display the original object graph
System.out.println("Original data structure: " + ds);
// Output it to a file
File f = new File("datastructure.ser");
System.out.println("Storing to a file...");
Serializer.store(ds, f);
// Read it back from the file, and display it again
ds = (DataStructure) Serializer.load(f);
System.out.println("Read from the file: " + ds);
// Create a deep clone and display that. After making the copy,
// modify the original to prove that the clone is "deep".
DataStructure ds2 = (DataStructure) Serializer.deepclone(ds);
ds.other.message = null; ds.other.data = null; // Change original
System.out.println("Deep clone: " + ds2);
}
}
}


/ 285