假设客户端具有类的对象,并且此类已更改为新状态。如果该类调用以前的状态,会发生什么?
示例:
我写了一节课如下
Class Old{
int a;
}
假设我创建了Class Old的新对象。我也序列化了这个对象。然后,我按如下方式更改Old类:
Class Old{
int a;
int b;
}
如果我尝试使用新的Old Class反序列化对象会怎样?
答案 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是类的唯一标识符,用于序列化。