1

假设一个客户有一个类的对象,并且这个类已经变成了新的状态。如果该类调用到以前的状态,会发生什么?

例子:

我写了一堂课如下

Class Old{
int a;
}

假设我创建了旧类的新对象。我也序列化了这个对象。然后,我将 Old 类更改如下:

Class Old{
int a;
int b;
}

如果我尝试用新的旧类反序列化对象会发生什么?

4

2 回答 2

3

由于客户端持有对对象的引用,因此它将始终访问当前对象及其当前状态。类的实例在它们变得陈旧或无效的意义上不是有状态的。

引用该实例的所有类都可以访问在一个地方对类实例的更改。

这个例子说明了上面的观点,因为类State,B,C都包含一个实例A,它指向内存中的同一个点,aka: reference。当类B更改时,更改的状态A是对类引用的内存中的实例State,B,C进行的。

不要认为它已C更改A,因此现在所有实例A都已更新。想得更像现在每个人都指向更新的对象。

这是一个非常简单的现实生活示例。假设我允许我所有的朋友编辑我的 LinkedIn 个人资料。将我的 LinkedIn 个人资料视为“A”。当我所有的朋友查看我的个人资料 (A) 时,他们会看到我作为 Web 应用程序开发人员的头衔。现在,如果我的一位朋友 (B) 访问我的个人资料并将我的头衔更改为 Hobo(字段),我的所有朋友 (A、B、C) 都会看到新头衔。为什么我的其他朋友 (State,C) 看不到“Web 应用程序开发人员”作为我的头衔(字段)?这是因为我的个人资料 (A) 有一个实例,并且任何有权访问它的人都查看或更新了相同的个人资料。

public class State {

    public static void main(String[] args) {
        A a = new A();
        B b = new B(a);
        C c = new C(a);

        System.out.println(a.field); //0
        System.out.println(b.a.field); //0
        System.out.println(c.a.field); //0

        b.change();

        System.out.println(a.field); //3
        System.out.println(b.a.field); //3
        System.out.println(c.a.field); //3

    }
}

class A{
    public Integer field = 0;
}

class B{
    public A a;

    public B(A a){
        this.a = a;
    }

    public void change(){
        this.a.field = 3;
    }
}

class C{
    public A a;

    public C(A a){
        this.a = a;
    }
}
于 2013-06-20T09:10:52.820 回答
0

正如 Kevin 所提到的,“由于客户端持有对对象的引用,因此它将始终访问当前对象及其当前状态。”

但是,如果您使用 RMI 和序列化,那么当您拥有的类和序列化字节之间的版本不匹配时,可能会出现反序列化问题。Java 会识别您要反序列化的字节是否与本地类版本匹配。如果不是,它将抛出异常。SerialVersionId 是类的唯一标识符,用于序列化。

于 2013-06-20T09:15:33.920 回答