如果对象调用先前状态的类函数会发生什么

时间:2013-06-20 09:09:27

标签: java

假设客户端具有类的对象,并且此类已更改为新状态。如果该类调用以前的状态,会发生什么?

示例:

我写了一节课如下

Class Old{
int a;
}

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

Class Old{
int a;
int b;
}

如果我尝试使用新的Old Class反序列化对象会怎样?

2 个答案:

答案 0 :(得分: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 Application Developer”视为我的标题(字段)?这是因为我的个人资料(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;
    }
}

答案 1 :(得分:0)

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

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