Java:当已经加载的类被反序列化时会发生什么

时间:2013-12-03 09:50:02

标签: java classloader

假设类com.Foo是从JAR加载的,后来是一个具有相同名称com.Foo的类,但不同的定义(其他字段)被反序列化(例如从DB加载或从远程呼叫)。

可能会产生什么后果?新收到的课程会有什么影响吗?假设该类在应用程序的其他部分中使用,后来保存在DB中并且序列化/ JSON编码。

2 个答案:

答案 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对象。