Java 为什么在父类中反序列化时不引发InvalidClassException
为什么我在尝试将子类读入父类变量时没有错误? 我认为在指定已读取的对象之前,编译器会检查两个类(变量类和已读取的类)的Java 为什么在父类中反序列化时不引发InvalidClassException,java,serialization,deserialization,Java,Serialization,Deserialization,为什么我在尝试将子类读入父类变量时没有错误? 我认为在指定已读取的对象之前,编译器会检查两个类(变量类和已读取的类)的serialVersionId,如果serialVersionId不相等,则会抛出InvalidClassException。那么A类和B类是否具有相同的serialVersionUID import java.io.*; class A {} class B extends A implements Serializable {} public class Test {
serialVersionId
,如果serialVersionId
不相等,则会抛出InvalidClassException
。那么A
类和B
类是否具有相同的serialVersionUID
import java.io.*;
class A {}
class B extends A implements Serializable {}
public class Test
{
public static void main(String[] args) throws IOException, ClassNotFoundException
{
FileOutputStream fileOutputStream = new FileOutputStream("b.bin");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
B b1 = new B();
objectOutputStream.writeObject(b1);
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream("b.bin");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
A a1 = (A) objectInputStream.readObject(); // why I don't have an InvalidClass Exception here
objectInputStream.close();
}
}
不,这两个类没有相同的
serialVersionUID
。没有引发异常,因为类B
可以成功重建。例如,当serialVersionUID
不匹配或A
不实现默认构造函数时,就会出现InvalidClassException
使用objectInputStream.readObject()
反序列化时,将返回一个对象
,该对象可以安全地强制转换到B
。由于B
扩展了A
,因此可以将其向上转换为A
类型的对象,就像在代码中发生的那样
另一方面,如果您使用序列化直接存储和检索对象,我强烈建议您为类定义一个serialVersionUID
您可以获得这两个类的
serialVersionUID
,如下所示:
ObjectStreamClass.lookup(A.class).getSerialVersionUID()
ObjectStreamClass.lookup(B.class).getSerialVersionUID()
这回答了你的问题吗?我知道了,但是JVM怎么知道我要反序列化哪个类呢?我的意思是,如果只看到
serialVersionUID
,为什么objectInputStream.readObject()
会准确返回B
类?@Denis\u newbie元数据根据。这包括TC\u CLASSDESC
常量后的完整类名,包括包。您可以查看存储的文件(b.bin
)并检查其内容。一个选项是hextump-cb.bin
。