按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
o1。writeObject(animals);
o1。writeObject(animals); // Write a 2nd set
// Write to a different stream:
ByteArrayOutputStream buf2 =
new ByteArrayOutputStream();
ObjectOutputStream o2 =
new ObjectOutputStream(buf2);
o2。writeObject(animals);
// Now get them back:
ObjectInputStream in1 =
new ObjectInputStream(
new ByteArrayInputStream(
buf1。toByteArray()));
ObjectInputStream in2 =
new ObjectInputStream(
new ByteArrayInputStream(
buf2。toByteArray()));
Vector animals1 = (Vector)in1。readObject();
Vector animals2 = (Vector)in1。readObject();
Vector animals3 = (Vector)in2。readObject();
System。out。println(〃animals1: 〃 + animals1);
System。out。println(〃animals2: 〃 + animals2);
System。out。println(〃animals3: 〃 + animals3);
} catch(Exception e) {
e。printStackTrace();
}
}
} ///:~
这里一件有趣的事情是也许是能针对一个字节数组应用对象的序列化,从而实现对任何Serializable (可序
列化)对象的一个“全面复制”(全面复制意味着复制的是整个对象网,而不仅是基本对象和它的句柄)。
复制问题将在第 12章进行全面讲述。
Animal 对象包含了类型为 House 的字段。在main()中,会创建这些Animal 的一个Vector,并对其序列化两
次,分别送入两个不同的数据流内。这些数据重新装配并打印出来后,可看到下面这样的结果(对象在每次
运行时都会处在不同的内存位置,所以每次运行的结果有区别):
animals: 'Bosco the dog'Animal@1cc76c'; House@1cc769
; Ralph the hamster'Animal@1cc76d'; House@1cc769
; Fronk the cat'Animal@1cc76e'; House@1cc769
'
animals1: 'Bosco the dog'Animal@1cca0c'; House@1cca16
; Ralph the hamster'Animal@1cca17'; House@1cca16
; Fronk the cat'Animal@1cca1b'; House@1cca16
327
…………………………………………………………Page 329……………………………………………………………
'
animals2: 'Bosco the dog'Animal@1cca0c'; House@1cca16
; Ralph the hamster'Animal@1cca17'; House@1cca16
; Fronk the cat'Animal@1cca1b'; House@1cca16
'
animals3: 'Bosco the dog'Animal@1cca52'; House@1cca5c
; Ralph the hamster'Animal@1cca5d'; House@1cca5c
; Fronk the cat'Animal@1cca61'; House@1cca5c
'
当然,我们希望装配好的对象有与原来不同的地址。但注意在 animals1 和animals2 中出现了相同的地址,
其中包括共享的、对House 对象的引用。在另一方面,当 animals3 恢复以后,系统没有办法知道另一个流内
的对象是第一个流内对象的化身,所以会产生一个完全不同的对象网。
只要将所有东西都序列化到单独一个数据流里,就能恢复获得与以前写入时完全一样的对象网,不会不慎造
成对象的重复。当然,在写第一个和最后一个对象的时间之间,可改变对象的状态,但那必须由我们明确采
取操作——序列化时,对象会采用它们当时的任何状态(包括它们与其他对象的连接关系)写入。
若想保存系统状态,最安全的做法是当作一种“微观”操作序列化。如果序列化了某些东西,再去做其他一
些工作,再来序列化更多的东西,以此类推,那么最终将无法安全地保存系统状态。相反,应将构成系统状
态的所有对象都置入单个集合内,并在一次操作里完成那个集合的写入。这样一来,同样只需一次方法调
用,即可成功恢复之。
下面这个例子是一套假想的计算机辅助设计(CAD )系统,对这一方法进行了很好的演示。此外,它还为我们
引入了static 字段的问题——如留意联机文档,就会发现Class 是“Serializable”(可序列化)的,所以
只需简单地序列化Class 对象,就能实现 static 字段的保存。这无论如何都是一种明智的做法。
//: CADState。java
// Saving and restoring the state of a
// pretend CAD system。
import java。io。*;
import java。util。*;
abstract class Shape implements Serializable {
public static final int
RED = 1; BLUE = 2; GREEN = 3;
private int xPos; yPos; dimension;
private static Random r = new Random();
private static int counter = 0;
abstract public void setColor(int newColor);
abstract public int getColor();
public Shape(int xVal; int yVal; int dim) {
xPos = xVal;
yPos = yVal;
dimension = dim;
}
public String toString() {
return getClass()。toString() +
〃 color'〃 + getColor() +
〃' xPos'〃 + xPos +
〃' yPos'〃 + yPos +
〃' dim'〃 + dimension + 〃'n〃;
}
public static Shape randomFactory() {
int xVal = r。nextInt() % 100;
328
…………………………………………………………Page 330……………………………………………………………
int yVal = r。nextInt() % 100;
int dim = r。nextInt() % 100;
switch(counter++ % 3) {
default:
case 0: return new Circle(xVal; yVal; dim);
case 1: return new Square(xVal; yVal; dim);
case 2: return new Line(xVal; yVal; dim);
}
}
}
class Circle extends Shape {
private static int color = RED;
public Circle(int xVal; int yVal; int dim) {
super(xVal; yVal; dim);
}
public void setColor(int newColor) {
color = newColor;
}
public int getColor() {
return color;
}
}
class Square extends Shape {
private static int color;
public Square(int xVal; int yVal; int dim) {
super(xVal; yVal; dim);
color = RED;
}
public void setColor(int newColor) {
color = newColor;
}
public int getColor() {
return color;
}
}
class Line extends Shape {
private static int color = RED;
public static void
serializeStaticState(ObjectOutputStream os)
throws IOException {
os。writeInt(color);
}
public static void
deserializeStaticState(ObjectInputStream os)
throws IOException {
color = os。readInt();
}
public Line (int xVal; int yVal; int dim) {
super(xVal; yVal; dim);