对象序列化的含义
对象序列化(Serialize)指将一个Java对象写入IO流中,对象的反序列化(Deserialize)则是指从IO流中恢复该Java对象。
如果想让某个Java对象能够序列化,则必须让它的类实现java.io.Serializable接口,接口定义如下:
public interface Serializable {
}
Serializable 接口是一个空接口,实现该接口无须实现任何方法,它只是告诉 JVM 该类可以被序列化机制处理。通常建议程序创建的每个 JavaBean 类都实现 Serializable。
序列化
对象序列化大致可分为两步:
- 创建一个对象输出流(ObjectOutputStream),可以包装一个其他类型的输出流,如文件输出流FileOutputStream。
- 通过对象输出流的writeObject()方法写对象,也就是输出可序列化对象。
通常,对象中的所有属性都会被序列化,但是对于一些比较敏感的信息,如用户的密码,一旦序列化后,人们完全可以通过读取文件或者拦截网络传输数据的方式获得这些信息。因此出于安全的考虑,某些属性应限制被序列化。解决的办法是使用transient来修饰。
反序列化
对象反序列化大致可分为两步:
- 创建一个对象输入流(ObjectInputStream),他可以包装一个其他类型的输入流,如文件输入流(FileInputStream)
- 通过对象输入流的readObject()方法读取对象,该方法返回一个Object类型的对象,如果程序知道该Java对象的类型,则可以将该对象强制转换成真是的类型。
如果向文件中使用序列化机制写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取。
如果一个可序列化的类,有多个父类(包括直接或间接父类),则这些父类要么是可序列化的,要么有无参构造方法,否则会抛出异常。
代码示例
-
学生类(Java实体类):
package demo3.exam;
import java.io.Serializable;
/**
* 可序列化 学生类
*/
public class student implements Serializable {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public student(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
}
-
manager类(方法实现类):
package demo3.exam;
import demo3.Student;
import java.io.*;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
/**
* 操作类
*/
public class StudentManager {
//新建列表
List<student> stulist=new ArrayList<>();
//初始化
public void init(){
student stu1=new student("哈哈哈","男",21);
student stu2=new student("行行行","女",22);
stulist.add(stu1);
stulist.add(stu2);
}
//保存 序列化
public void save(File path) throws IOException {
//定义对象输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(path));
//序列化
oos.writeObject(stulist);
oos.close();
}
//读取 反序列化
public void read(File path) throws IOException, ClassNotFoundException {
//创建对象输入流
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(path));
//反系列化(强制类型转换)
stulist=(ArrayList<student>)ois.readObject();
ois.close();
}
//输出
public void show(){
for (student student : stulist) {
System.out.println("姓名:" + student.getName()+"\t性别:"+student.getSex()+"\t年龄:"+student.getAge());
}
}
}
-
测试类
package demo3.exam;
import java.io.File;
import java.io.IOException;
public class studentTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//新建file对象
File path=new File("c:/Users/29616/desktop/stu.txt");
StudentManager manager=new StudentManager();
//反序列化
try {
manager.read(path);
System.out.println("读取成功");
//输出
manager.show();
}catch (Exception e){
//初始化
manager.init();
//序列化
manager.save(path);
//序列化成功
System.out.println("序列化完成");
}
}
}