如果真如你所说的,A、B两个类的对象仅仅是保持指向同一个C类对象的引用而非包含,那么,A、B类中引用的永远是同一个C类对象。所以,你完全不用担心A类对象对C的对象会有何影响,只需要你保证将同一个C类对象的引用传给新生成的C类对象就可以了。

解决方案 »

  1.   

    我是照你说的那样做的,但事实上结果并不像希望的那样。下面有个例子,有空的环帮忙看一下,也可以直接运行的,你可以试一下。
    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 " );
    }
    }
      

  2.   

    事实上,在执行完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);
      

  3.   

    首先谢谢你的关心。不过我还有个问题。
    你说的是一个办法,不过上面的例子只是一个十分简单的例子。而到了比较复杂的系统中,就不一定能判断是否temp已经改变。
    而且,再次读入后也不一定能够找到temp(因为系统中的对象是很多的,而且会在不同的地方被修改)。
    有没有什么其他的方法呢?
    能不能让系统自己去完成这样的工作能?
      

  4.   

    你的情况一般应该这样做: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()即可。这样的设计模式就能达到你的目的。
      

  5.   

    谢谢楼上的答案,我确实希望有一种类似的设计模式可以解决我的问题。而且你的答案也解决了我上面的程序里的问题。不过看来是我给了例子不好,没能详细的描述我的问题。实际中的操作是这样的话该怎么办呢??有a1,b1共同指向c1然后又有a2,b2=>c2;a3,b3=>c3;....其问题是先保存了所有的a类对象。然后会有随机的可能性对b类对象中的c作修改,之后再读取a这时a里的c没有改变。而用楼上提出的方法似乎也不行。
      

  6.   

    我觉得你的问题在于在保存类A的对象时不应该用同时保存C的内容或连接,因为事实上,当用保存的某个静态A对象数据构造一个新的A对象时,主控程序很难判断哪个C类的对象跟它是相关联的。如果你可以说明或解决A对象身份的问题,序列化的同步就简单了。
      

  7.   

    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.
      

  8.   

    大家都提到了要单独保存c类对象,我想这是一个可行的方法。但正如楼上所说可能会比较复杂。我想我不如脸皮厚点,在向大家讨教一下,如果改变设计该如何去做。问题的根本是这样的。一个学生选课系统,有课程(A)、学生(B)两个类我设计了一个关联类C作为学生与课程之间的桥梁,只要学生选了课就会生成一个对应的C类对象。
    那么在我不想把C类取消的情况下,该如何设计能?
    谢谢关心。
      

  9.   

    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.
      

  10.   

    楼上的意思是不是就是把所有的学生和课程都统一保存在一个类里,再对应的存储他们的注册信息??这样似乎和 ajoo(jet pig) 提到的用hascode存储对象id的思路差不多。我觉得也只有这样解决比较好了。集思广益,还有人有什么思路吗?
      

  11.   

    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);
      

  12.   

    有点不大懂了,Acad与Course&Student是什么关系呢?
    原来的Registration类是一个关联类,
    一个学生或课程可以与多个Registration关联,但每个Registration只能与一个学生和一个课程关联啊?那么Acad起到了什么作用呢?它里面有多个学生多个课程却只有一个Registration??
      

  13.   

    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.