如果我尝试从文件中加载旧版本的对象会怎样?
例如,如果我创建了一个对象,然后使用 FileOutputStream 将该对象保存到一个文件中。然后,如果我添加了一个字段,并尝试重新加载此对象,Java 将根本无法识别该对象,还是会将字段设置为默认值或...?
谢谢 :)
如果我尝试从文件中加载旧版本的对象会怎样?
例如,如果我创建了一个对象,然后使用 FileOutputStream 将该对象保存到一个文件中。然后,如果我添加了一个字段,并尝试重新加载此对象,Java 将根本无法识别该对象,还是会将字段设置为默认值或...?
谢谢 :)
InvalidClassException
当您尝试使用不同的类版本反序列化您的类时,您应该收到一个。从javadocs:
序列化运行时与每个可序列化类关联一个版本号,称为 serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送方和接收方是否已加载与序列化兼容的该对象的类。如果接收者为对象加载了一个类,该对象的 serialVersionUID 与相应发送者的类不同,则反序列化将导致 InvalidClassException。可序列化的类可以通过声明一个名为“serialVersionUID”的字段来显式声明自己的serialVersionUID,该字段必须是静态的、最终的和long类型:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 如果可序列化类没有显式声明 serialVersionUID,则序列化运行时将根据类的各个方面为该类计算默认的 serialVersionUID 值,如 Java(TM) 对象序列化规范中所述。但是,强烈建议所有可序列化的类都显式声明 serialVersionUID 值,因为默认的 serialVersionUID 计算对类细节高度敏感,这些细节可能因编译器实现而异,因此可能在反序列化期间导致意外的 InvalidClassExceptions。因此,为了保证不同 java 编译器实现的 serialVersionUID 值一致,可序列化的类必须声明一个显式的 serialVersionUID 值。还强烈建议显式 serialVersionUID 声明尽可能使用 private 修饰符,因为此类声明仅适用于立即声明的类——serialVersionUID 字段不能用作继承成员。
您很可能会遇到异常,因为存储在文件中的 serialVersionUID 与当前版本的类不匹配。
默认情况下,Java 只会出错。
如果您想提供一种读取“旧版本”的方法,则必须实现 readObject 方法。
在序列化和反序列化过程中需要特殊处理的类必须实现具有这些确切签名的特殊方法:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;