假设类com.Foo
是从JAR加载的,后来是一个具有相同名称com.Foo
的类,但不同的定义(其他字段)被反序列化(例如从DB加载或从远程呼叫)。
可能会产生什么后果?新收到的课程会有什么影响吗?假设该类在应用程序的其他部分中使用,后来保存在DB中并且序列化/ JSON编码。
答案 0 :(得分:1)
你对Serialization
的工作方式有错误的想象。您可以像对象其他对象一样将Class
实例写入对象流,但这将不将该类的字节代码及其定义写入流中。它只是创建一个类的符号引用,它像流的任何其他类引用一样被解析:通过使用其符号名称尝试在反序列化它的类的上下文中解析它。它不会创建新类。
实际上,java.lang.Class
的实例创建的实际类依赖性比创建它的实例更少。该实例取决于序列化形式,例如类的非transient
字段,而java.lang.Class
实例表示的符号引用不依赖于它。
当编写流时出现的类与反序列化时出现的类之间的兼容性由serialVersionUID
确定,如果它不匹配,则反序列化将始终失败并出现异常。如果匹配,则实施将尽力恢复。流中不存在的字段将获取其默认值,实际类中不存在的流字段以及任何其他未处理的额外数据将被忽略。
答案 1 :(得分:1)
如果反序列化Class<?>
对象,则会加载具有完全限定类名的类。如果它已经加载,您将获得该类的引用。
我认为如果需要完整答案,请阅读Java Object Serialization Specification
以下是我认为非常有用的规范中的一些引用:
1.1概述
数组,枚举常量以及Class,ObjectStreamClass和String类型的对象需要特殊处理。其他对象必须实现Serializable或Externalizable接口才能保存在流中或从流中恢复。
2。对象输出类
如果对象是Class,则将相应的ObjectStreamClass写入流中,为该类分配句柄,并返回writeObject。
3。对象输入类
如果流中的对象是Class,请读取其ObjectStreamClass描述符,将其及其句柄添加到已知对象集中,并返回相应的Class对象。