Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。
deserialization(反序列化):将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化。
序列化就好比将一只动物的基因分解,封装在一个容器中;反序列化就是将容器中封装的基因序列拿出来重新组装成一只动物,组装前和组装后的动物是不同的,但是基因是一样的。
下面来实现一个序列化:
1.首先创建一个Student对象
public class Student implements Serializable {
private String name;// 姓名
private String gender;// 性别
private Integer age;// 年龄
public Student() {// 无参构造
}
public Student(String name, String gender, Integer age) {// 有参构造
this.name = name;
this.gender = gender;
this.age = age;
}
@Override
public String toString() {// toString()方法
return "Student{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
public String getName() {// get方法
return name;
}
public void setName(String name) {// set方法
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
注意!这里的Student类要实现一个Serializable接口,否则会报NotSerializableException(没有序列化异常)
2.给Student对象赋值,在控制台可以打印一下
Student student = new Student("小明", "男", 15);
System.out.println(student.getName());
System.out.println(student.getGender());
System.out.println(student.getAge());
序列化用到两个类:
(1)FileOutputStream:文件字节输出流。
是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。
(2)ObjectOutputStream:对象输出流。
将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。
public static void main(String[] args) {
// 序列化 将student类的对象序列化到abc.txt文件中
Student student = new Student("小明", "男", 15);
System.out.println(student.getName());
System.out.println(student.getGender());
System.out.println(student.getAge());
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream("./resources/bb.txt");
oos = new ObjectOutputStream(fos);
oos.writeObject(student);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
控制台输出:
序列化后再路径下面会生成对应的文件:
但是生成的文件打开后是乱码:
这个乱码文件不是我们代码写错了,而是用计算机语言存储的一个二进制文件,后续进行反序列化就可以直接将这个二进制文件变为Student对象。
实现反序列化也用到两个类:
(1)FileInputStream:文件字节输入流。
是Java语言中抽象类InputStream用来具体实现类的创建对象。FileInputStream可以从文件系统中的某个文件中获得输入字节,获取的文件可用性取决于主机环境。FileInputStream的构造方法需要指定文件的来源,通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
(2)ObjectInputStream:对象输出流。
从流中读入一个用户自定义的对象。一定要注意ObjectOutputStream与ObjectInputStream必须配合使用,且按同样的顺序。
public static void main(String[] args) {
// 反序列化
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("./resources/bb.txt");
ois = new ObjectInputStream(fis);
Student student = (Student)ois.readObject();
System.out.println(student.getName());
System.out.println(student.getAge());
System.out.println(student.getGender());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
fis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化时还要注意要将读取的对象强转为Student类: