1、序列化
序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
1)序列化: 将数据结构或对象转换成二进制串的过程
2)反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程
2、对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
3、Java类库的序列化API
ObjectOutputStream代表对象输出流,它的writeObject(Objectobj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。
4、对象序列化包括如下步骤:
1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
2) 通过对象输出流的writeObject()方法写对象。
5、对象反序列化的步骤如下:
1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
2) 通过对象输入流的readObject()方法读取对象。
6、示例
首先我们新建一个学生类,包括姓名,年龄,性别,身高,四个属性:
package com.Serialization;
import java.io.Serializable;
/**
* 这是一个学生类,实现了Serializable接口,可以被序列化
*/
public class Student implements Serializable {
//姓名
private String name;
//年龄
private int age;
//性别
private String sex;
//身高
private double height;
// 不带参构造方法
public Student() {
}
//带参构造方法
public Student(String name, int age, String sex, double height) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", height=" + height +
'}';
}
}
然后新建一个用于序列化输出的类:
package com.Serialization;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
/**
* 这是一个序列化输出的测试类
*/
public class OutputDemo {
public static void main(String[] args) {
//实例化一个学生对象
Student student=new Student("李佳奇",12,"女",170.0);
//实例化一个文件对象
File file=new File("D:/student.txt");
//声明一个序列化输出流
ObjectOutputStream oos=null;
//如果文件不存在,就创建文件
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//实例化序列化输出流,指定输出文件
oos=new ObjectOutputStream(new FileOutputStream(file));
//将学生对象序列化输出
oos.writeObject(student);
System.out.println("序列化输出成功");
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭序列化输出流
if (oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这里我们运行程序,控制台输出:
再去看文件夹:
可以看到是一堆乱码,这是因为我们输出的时二进制字节,我们可以读取后再看看具体信息,所以我们再建一个用于序列化输入(反序列化)的类:
package com.Serialization;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class InputDemo {
public static void main(String[] args) {
//实例化一个学生类用来接收反序列化输入的对象
Student student=new Student();
//新建文件对象
File file=new File("D:/student.txt");
//声明一个序列化输入流
ObjectInputStream ois=null;
try {
//实例化序列化输入流,指定输入文件
ois=new ObjectInputStream(new FileInputStream(file));
//读取文件里的对象
student= (Student) ois.readObject();
//在控制台打印对象信息
System.out.println(student);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行这个程序后,控制台输出:
可以看到这正是我们序列化输出的信息!
如果我们一次想序列化输出多个对象,我们可以利用集合,将多个对象添加进集合,然后序列化输出结合对象,当然反序列化的时候我们得到的是一个集合对象,遍历这个集合就可以得到多个对象的信息。