一、序列化
利用ObjectOutputStream,把对象信息,按照固定格式转成一串字节输出并持久保存到磁盘中。
1、序列化:把对象的信息保存到文件中,输出-->OOS。
2、准备Student类,注意:需要实现可序列化接口(Serializable接口)。
3、创建序列化流对象。
4、创建被序列化输出的学生类对象。
5、用流将对象输出,用到的方法out.writeObject();
代码示例:
学生类:
/*本类用于封装学生类*/
/*如果本类的对象想要被序列化输出,必须实现可序列化接口Serializable,
* 标志当前这个类的对象可以被序列化*/
public class Student implements Serializable {
/*手动将序列化版本号写成一个固定值*/
private static final long serialVersionUID = 1L;
//1.定义学生的相关属性并封装
private String name;
private int age;
private String addr;//住址
private char gender;//性别
//2.创建本类的无参构造
public Student(){
System.out.println("我是Student类的无参构造");
}
//3.创建本类的全参构造
public Student(String name, int age, String addr, char gender) {
this.name = name;
this.age = age;
this.addr = addr;
this.gender = gender;
System.out.println("我是Student类的全参构造");
}
//4.提供所有被封装属性的get与set方法
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 getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
//如果不想打印对象的地址值,需要重写toString();
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", addr='" + addr + '\'' +
", gender=" + gender +
'}';
}
}
测试类:
/*序列化方法*/
private static void method1() {
//1.声明一个在本方法中都生效的局部变量,局部变量需要初始化
ObjectOutputStream out = null;
//2.由于IO操作可能会抛出异常,所以需要完成try-catch-finally结构
try {
//3.创建流对象
out = new ObjectOutputStream(
new FileOutputStream("D:\\ready\\1.txt"));
//4.指定要序列化(输出)的对象
Student obj = new Student("少爷少爷",22,"武汉",'男');
//5.通过OOS流对象来序列化输出Student的对象
out.writeObject(obj);
System.out.println("序列化成功!");
}catch (Exception e){
System.out.println("序列化失败");
e.printStackTrace();
}finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、反序列化
利用ObjectInputStream,读取磁盘中之前序列化好的数据,重写恢复成对象。
1、反序列化:把之前序列化输出的对象数据,重写在程序中恢复成对象,输入-->OIS。
2、创建反序列化流对象。
3、用流对象恢复序列化输出的对象。
注意:自定义类需要重写toString()才能查看对象的属性与属性值,否则打印地址值。
代码示例:
测试类:
/*反序列化方法*/
private static void method2() {
//1.声明一个在本方法中都生效的局部变量,局部变量需要初始化
ObjectInputStream in = null;
//2.由于IO操作可能会抛出异常,所以需要完成try-catch-finally结构
try {
//3.创建反序列化(输入流)对象
in = new ObjectInputStream(
new FileInputStream("D:\\ready\\1.txt"));
System.out.println(in.readObject());
System.out.println("反序列化成功!");
}catch (Exception e){
System.out.println("反序列化失败!");
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化如何成功:
核心:Student类中的UID,与反序列化流中的UID保持一致。
1、一次序列化对应一次反序列化【推荐】。
2、一个序列化后不修改Student中的内容,然后反序列化。
3、将Student中的UID写成固定值。
注意:反序列化持有的UID与Student类中UID不一致时,反序列化会失败
比如:使用自动生成的UID,先序列化,然后修改Student,再来反序列化,这样就会失败。