本文已参与[新人创作礼]活动,一起开启掘金创作之路.
本文档由该视频整理:视频链接
什么是序列化和反序列化
序列化: Serializable将java对象存储到文件中,将java对象的状态保存下来的过程。 反序列化: DeSerializable将硬盘上的数据重新恢复到内存当中,恢复成java对象。
序列化的要求
- 参与序列化和反序列化的对象,必须实现Serializable接口。
- 注意:通过源代码发现,Serializable接口只是一个标志接口;
public interface Serializable{
}
Serializable接口的作用
起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,会为这个类生成一个序列化版本号。
序列化和反序列化的实现
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Test {
public static void main(String[] args) {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// 创建java对象
Student s = new Student("张三");
// 序列化
oos = new ObjectOutputStream(new FileOutputStream("文件路径"));
// 序列化对象
oos.writeObject(s);
// 刷新
oos.flush();
// 反序列化
ois = new ObjectInputStream(new FileInputStream("文件路径"));
Object obj = ois.readObject();
System.out.println(obj);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (oos != null) {
// 关闭
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class Student implements Serializable {
private String name;
public Student(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}
transient关键字
如果不希望对象的某个属性不参与序列化操作,可以为该属性加上transient关键字修饰
java语言中是采用什么机制来区分类的?
第一:首先通过类名进行比对,如果类名不一样,肯定不是同一个类。 第二:如果类名一样,再怎么进行类的区别?靠序列化版本号进行区分。
自动生成序列化版本号有什么缺陷?
对于实现Serializable接口的类,一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。(这样就不好了!)
手动编写序列化版本号
- 好处:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。
- 在类中增加该属性即可:
private static final long serialVersionUID