序列化
1.介绍
序列化:指把Java堆内存中的对象数据,通过某种方式把对象数据存储到磁盘文件中或者传递给给网络上传输。序列化在分布式系统在应用非常广泛
反序列化:把磁盘文件中的对象的数据或者把网络节点上的对象数据恢复成Java对象的过程。需要做序列化的类必须实现序列化接口:java.io.Serializable(这是标志接口[没有抽象方法])
2.使用
public class ObjectOutputStreamDemo {
public static void main(String[] args) {
Student s = new Student("小黑",19);
//1.
ObjectOutputStream obj = null;
try {
obj = new ObjectOutputStream(new FileOutputStream("object.txt"));
//2.具体操作
obj.writeObject(s);//
obj.flush();//刷新
} catch (IOException e) {
e.printStackTrace();
} finally {//3、关闭流
try {
if (obj != null)
obj.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
注意事项:
①对象一定要实现Serializable接口(代表可以序列化)
②使用的通道流是ObjectOutputStream。
③写出操作调用的方法是writeObject()
3. transient 关键字
字段使用transient 修饰则不会被序列化
4. serialVersionUID
当类实现Serializable接口后,在编译的时候就会根据字段生成一个缺省的serialVersionUID值,并在序列化操作时,写到序列化数据文件中。但随着项目的升级系统的class文件也会升级(增加一个字段/删除一个字段),此时再重新编译,对象的serialVersionUID值又会改变。
如果值不相同(意味着类的版本不同),那么报异常InvalidClassException,即:类版本不对应,不能进行反序列化。如果版本号相同,则可以进行反序列化
解决:在开发中我们可以故意在类中提供一个固定的serialVersionUID值。
public static final long serialVersionUID = 748641631L;//值可以随便写
总结:
①对应的类要实现Serializable接口
②然后使用ObjectOutputSream类 以及writeObject方法writeObject(stu),写出的文件中内容是乱码的(因为这不是给我们看的,是给我们进行反序列化操作的文件)
③实现了Serializable接口后,其实类中会默认的分配一个全局常量serialVersonUID 他是固定不变的,如果我们序列化之后的文件,类又改变过结构,那么反序列化时就会出现java.io.InvalidClassException (类版本不对应,不能进行反序列化)
因为类的结构改变之后,serialVersionUID也会改变,所以我们一般显示的定义一个全局常量的serialVersionUID值
public static final long serialVersionUID = 44113L;(这个值是随便写都可以)这样无论结构如果改变,反序列化操作都不会出错