假设一个客户有一个类的对象,并且这个类已经变成了新的状态。如果该类调用到以前的状态,会发生什么?
例子:
我写了一堂课如下
Class Old{
int a;
}
假设我创建了旧类的新对象。我也序列化了这个对象。然后,我将 Old 类更改如下:
Class Old{
int a;
int b;
}
如果我尝试用新的旧类反序列化对象会发生什么?
假设一个客户有一个类的对象,并且这个类已经变成了新的状态。如果该类调用到以前的状态,会发生什么?
例子:
我写了一堂课如下
Class Old{
int a;
}
假设我创建了旧类的新对象。我也序列化了这个对象。然后,我将 Old 类更改如下:
Class Old{
int a;
int b;
}
如果我尝试用新的旧类反序列化对象会发生什么?
由于客户端持有对对象的引用,因此它将始终访问当前对象及其当前状态。类的实例在它们变得陈旧或无效的意义上不是有状态的。
引用该实例的所有类都可以访问在一个地方对类实例的更改。
这个例子说明了上面的观点,因为类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;
}
}
正如 Kevin 所提到的,“由于客户端持有对对象的引用,因此它将始终访问当前对象及其当前状态。”
但是,如果您使用 RMI 和序列化,那么当您拥有的类和序列化字节之间的版本不匹配时,可能会出现反序列化问题。Java 会识别您要反序列化的字节是否与本地类版本匹配。如果不是,它将抛出异常。SerialVersionId 是类的唯一标识符,用于序列化。