我是照你说的那样做的,但事实上结果并不像希望的那样。下面有个例子,有空的环帮忙看一下,也可以直接运行的,你可以试一下。 import java.io.*; public class SerizableTest { public static void main( String args[] ) { C temp = new C();
A a = new A(temp ); B b = new B(temp );
try{ ObjectOutputStream output = new ObjectOutputStream( new FileOutputStream( "aFile" ) ); output.writeObject( a ); output.flush(); output.close(); }catch( IOException e ) { }
b.m_BC.data = "modify"; try{ ObjectOutputStream output = new ObjectOutputStream( new FileOutputStream( "bFile" ) ); output.writeObject( b ); output.flush(); output.close(); }catch( IOException e ) { }
try{ ObjectInputStream input = new ObjectInputStream( new FileInputStream( "aFile" ) ); a= (A) input.readObject(); }catch( Exception e ){} System.out.println( "A: "+a.m_AC.data ); System.out.println( "B: "+b.m_BC.data );
} }class A implements Serializable { C m_AC;
A( C ac ) { m_AC = ac; }
}class B implements Serializable { C m_BC;
B( C bc ) { m_BC = bc; }
}class C implements Serializable { String data;
C() { data = new String(" ini " ); } }
事实上,在执行完a= (A) input.readObject(),a中包含的C类对象已经是根据存储的数据生成的一个新的C类对象,不再是那个temp了。所以在你的例子里,每次重新导入新的a时,都必须重新将temp设为m_AC的当前引用。即在A类中增加 class A{ ... public void setC( C ac ) { m_AC = ac; } ... }并在a= (A) input.readObject()后添加: a.setC(temp);
你的情况一般应该这样做:public class C { private static C constant = null; private C //构造 { } public synchronized static C getInstance() { if( constant == null ) constant = new C(); return constant; }}这样,你在系统中多个类中对C类的引用做修改时,使用C.getInstance()即可。这样的设计模式就能达到你的目的。
It's quite hard. my friend. the default serialization will not guarantee identity consistency across different serializations.so, if you have object graph like d refers to a and b, a refers to c, b refers to c. writeObject(d) and d=readObject() will make sure you still get the exact object layout.But, if you call a=readObject(), b=readObject(), a and b may not be refering to the same c object.a possible solution would be: override the writeObject and readObject, save the object id instead of the object itself when you are serializing c. then, use a hashtable to store the mapping between the object id and the object.But, this does not always solve the problem. If you have a circular reference, it'll be very hard, if possible.So, perfect solution would be to try serializing the whole object graph in one serialization. if you cannot do that, think about your design first.
don't put registration info into course or student. use a Registration class to do that. then, class Acad implements Serializable{ private Student[] students; private Course[] courses; private Registration reg; } then serialize Acad.
1. hashcode cannot be object id, it is not unique 2. with the Acad object, you don't need object id. the serialization will take care of the identity consistency for you when you do writeObject(acad);
the point is, you have to call writeObject for ONCE. and then, writeObject can take care of the consistency. if you call writeObject(students), writeObject(registration), writeObject(courses) individually, it does not guarantee that.
import java.io.*;
public class SerizableTest
{
public static void main( String args[] )
{
C temp = new C();
A a = new A(temp );
B b = new B(temp );
try{
ObjectOutputStream output = new ObjectOutputStream(
new FileOutputStream( "aFile" ) );
output.writeObject( a );
output.flush();
output.close();
}catch( IOException e ) { }
b.m_BC.data = "modify";
try{
ObjectOutputStream output = new ObjectOutputStream(
new FileOutputStream( "bFile" ) );
output.writeObject( b );
output.flush();
output.close();
}catch( IOException e ) { }
try{
ObjectInputStream input = new ObjectInputStream(
new FileInputStream( "aFile" ) );
a= (A) input.readObject();
}catch( Exception e ){}
System.out.println( "A: "+a.m_AC.data );
System.out.println( "B: "+b.m_BC.data );
}
}class A implements Serializable
{
C m_AC;
A( C ac )
{
m_AC = ac;
}
}class B implements Serializable
{
C m_BC;
B( C bc )
{
m_BC = bc;
}
}class C implements Serializable
{
String data;
C()
{
data = new String(" ini " );
}
}
class A{
... public void setC( C ac )
{
m_AC = ac;
} ...
}并在a= (A) input.readObject()后添加:
a.setC(temp);
你说的是一个办法,不过上面的例子只是一个十分简单的例子。而到了比较复杂的系统中,就不一定能判断是否temp已经改变。
而且,再次读入后也不一定能够找到temp(因为系统中的对象是很多的,而且会在不同的地方被修改)。
有没有什么其他的方法呢?
能不能让系统自己去完成这样的工作能?
{
private static C constant = null; private C //构造
{
} public synchronized static C getInstance()
{
if( constant == null )
constant = new C();
return constant;
}}这样,你在系统中多个类中对C类的引用做修改时,使用C.getInstance()即可。这样的设计模式就能达到你的目的。
the default serialization will not guarantee identity consistency across different serializations.so, if you have object graph like d refers to a and b, a refers to c, b refers to c.
writeObject(d) and d=readObject() will make sure you still get the exact object layout.But, if you call a=readObject(), b=readObject(), a and b may not be refering to the same c object.a possible solution would be:
override the writeObject and readObject, save the object id instead of the object itself when you are serializing c.
then, use a hashtable to store the mapping between the object id and the object.But, this does not always solve the problem. If you have a circular reference, it'll be very hard, if possible.So, perfect solution would be to try serializing the whole object graph in one serialization.
if you cannot do that, think about your design first.
那么在我不想把C类取消的情况下,该如何设计能?
谢谢关心。
use a Registration class to do that.
then,
class Acad implements Serializable{
private Student[] students;
private Course[] courses;
private Registration reg;
}
then serialize Acad.
2. with the Acad object, you don't need object id. the serialization will take care of the identity consistency for you when you do writeObject(acad);
原来的Registration类是一个关联类,
一个学生或课程可以与多个Registration关联,但每个Registration只能与一个学生和一个课程关联啊?那么Acad起到了什么作用呢?它里面有多个学生多个课程却只有一个Registration??
and then, writeObject can take care of the consistency.
if you call writeObject(students), writeObject(registration), writeObject(courses) individually,
it does not guarantee that.