概述
对象序列化:
所谓的对象序列化就是将对象保存到磁盘中,或者在网络中传输对象。
这种机制就是使用一个字节序列表示一个对象,该字节序列包含:
- 对象的类型
- 对象的数据
- 对象中存储的属性等信息
字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
对象反序列化:
对象反序列化就是将 对象的字节序列从文件中读取回来,重构对象,对它进行反序列化。
对象序列化准备工作
实现Serializable
接口
如果要将,对象序列化,该对象必须实现Serializable
接口,如下:
1 | class People implements Serializable { |
Serializable
接口表示该类 启用 类的序列化,也就是允许该类被序列化。该接口没有实现方法,只是一个标识性的接口。
如果需要序列化或者反序列化的类不实现该接口,那么在序列化或者序列化过程中抛出异常NotSerializableException
。
最好显式声明一个serialVersionUID
什么是
serialVersionUID
?序列化运行时将每个可序列化的类与称为
serialVersionUID
的版本号相关联。该序列号在反序列化期间用于验证序列化对象的发送者和接收者是否已加载与该序列化兼容的对象的类。 如果接收方加载了一个具有不同于相应发件人类的
serialVersionUID
的对象的类,则反序列化将导致InvalidClassException
。简而言之:
相当于Java的版本号,保证序列化的对象 和 反序列化兼容的对象 的版本相同才能反序列化。
如果没有显式地声明一个serialVersionUID
则序列化运行时将根据**Java(TM)对象序列化规范中所述的类的各个方面**计算该类的默认serialVersionUID
值
默认的serialVersionUID
计算对类详细信息非常敏感,这可能会因编译器实现而异,因此可能会在反InvalidClassException
化期间导致InvalidClassException
的InvalidClassException
。
比如将如下类的对象序列化
1 | class People implements Serializable { |
然后在反序列化之前,修改这个类,添加一个属性或者删除一个属性
1 | class People implements Serializable { |
就会抛出InvalidClassException
异常。异常信息:
stream classdesc serialVersionUID = 6500785223629970781, local class serialVersionUID = -4354424114631597798
异常信息表明,流对象发”版本号“是6500785223629970781,当前接收的类的”版本号“是-4354424114631597798。
版本号不一致!这说明默认的serialVersionUID
对类的细节非常敏感!
但如果我们显式的声明serialVersionUID
就不会出现这种问题。需要说明的是,**该字段必须是静态的,最终的,类型是long
**
显式声明一个serialVersionUID
1 | class People implements Serializable { |
其他需要注意的
- 序列化的类必须有可访问的无参构造函数
- 序列化的类不能包含未知的数据类型
否则都会引发InvalidClassException
异常。
如果你不想类中某个字段不被序列化,可以使用transient
关键字修饰。
对象序列化
- 对象序列化使用
objectOutputStream
类。- 方法:
void writeobject (object obj)
:将指定的对象写入objectOutputStream
- 方法:
- 反序列化使用
objectInputStream
类。- 方法:
object read0bject ()
:从objectInputStream
读取一个对象
- 方法:
了解一下就行了,真正开发时,用的很少。
1 | public class UID { |
1 | class People implements Serializable { |
__END__