ObjectOutputStream:
内存 ------序列化(拆分对象)------>硬盘
ObjectInputStream:
硬盘 ------反序列化(组装对象)------>内存
序列化Serialize
: 将内存中的java对象存储到硬盘文件中。
反序列化DeSerialize
: 将硬盘上的数据重新恢复到内存中。
参与序列化和反序列化的对象,必须实现Serializable接口。
Serializable接口源码:
public interface Serializable {
}
这个接口里面没有代码。
作用:起到标识的作用,java虚拟机看到类实现了这个接口后,会自动生成一个序列化版本号。
序列化版本号的作用:
- java语言区分类的机制:先比对类名,类名一样,再比对序列化版本号。
- 自动生成序列化版本号缺点:一旦代码确定之后,不能进行后续的修改。因为只要进行修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。
- 只要是实现了Serializable接口,建议固定序列化版本号。
private static final long serialVersionUID = 1L;
实体类
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private int no;
private String name;
private transient String classroom; //加transient关键字,表示游离的,不参与序列化操作
// 省略有参,无参,get,set,toString
}
序列化
/**
* 序列化
* 参与序列化的类型必须实现java.io.Serializable接口。
* 不实现会出现java.io.NotSerializableException异常.
*/
public class ObjectOutputStreamTest {
public static void main(String[] args) throws Exception {
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students"));
// 序列化一个对象
// 创建java对象
Student stu = new Student(1, "lwx","201");
// 序列化对象
oos.writeObject(stu);
//序列化多个对象
List<Student> studentList = new ArrayList<>();
studentList.add(new Student(2,"asd","202"));
studentList.add(new Student(3,"zxc","203"));
oos.writeObject(studentList);
// 刷新
oos.flush();
//关闭
oos.close();
}
}
反序列化
/**
* 反序列化
*/
public class ObjectInputStreamTest {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
// 反序列化一个对象
Object obj = ois.readObject();
System.out.println(obj); //Student{no=1, name='lwx', classroom='null'}
// 反序列化多个对象
/*Object obj1 = ois.readObject();
System.out.println(obj1 instanceof List); //true*/
List<Student> studentList = (List<Student>)ois.readObject();
for (Student student : studentList) {
System.out.println(student);
}
// 关闭
ois.close();
}
}
工具生成序列化版本号
在设置中勾选
Alt+回车enter
生成