定义:
- 序列化
将内存中的对象写入到硬盘文件中 - 反序列化
将硬盘文件中的对象数据读入到内存中
实现:
- 要操作的类一定要实现 Serializable 接口,类中所引用的类型的类也要实现 Serializable 接口,以此类推。Serialable 接口对 JVM 起到标识作用,实现类无需重写方法。只有实现了 Serializable 接口的类所产生的对象才能被序列化与反序列化
- 对象输出流 ObjectOutputStream 起到序列化的作用,对象输入流 ObjectInputStream 起到反序列化的作用
序列化版本号
序列化版本号是类的标识,将序列化好的对象与它对应的类联系起来。类的自定义序列化版本号是静态常量。
public class Roster implements Serializable {
//自定义序列化版本号
private static final long serialVersionUID = 1L;
}
序列化好的对象可以通过序列化版本号找到它所对应的类。
如果类没有自定义序列化版本号,JVM 将分配版本号,对类做出更改后,类又被分配新的版本号,这时,原来的类的已经序列化好的对象就无法反序列化了,因为原来的版本号没有所对应的类了。
对于有自定义序列化版本号的类,对类做出修改后,原来就序列化好的对象能够反序列化,缺的属性增加上,赋默认值;多出来的属性舍弃。为了数据的正常存储,序列化版本号应当是自定义的全球独一无二的。
实例:
在第一次序列化前,不要执行反序列化,因为空文件无法被反序列化
第一次运行:
import java.io.*;
import java.util.Scanner;
//测试类
public class Test {
//main方法
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Person p1 = new Person(1001,"张三");
//第一次运行程序时不执行反序列化,因为空文件无法被反序列化
// //反序列化
// System.out.println("从硬盘文件读入数据");
// Deserialization deserialization = new Deserialization();
// p1 = (Person)deserialization.deserialize();
//输出信息
System.out.println(p1);
System.out.println("请输入新名字");
String name = in.next();
p1.setName(name);
System.out.println("修改成功");
System.out.println(p1);
//序列化
Serialization serialization = new Serialization(p1);
System.out.println("保存成功");
System.out.println("程序退出");
System.exit(1);
}
}
//序列化类
class Serialization {
public Serialization(Object object) {
//创建对象输出流
ObjectOutputStream oos = null ;
//操作流
try {
//序列化,把内存中的对象写入到硬盘文件 Roster.dat 中
oos = new ObjectOutputStream(new FileOutputStream("D:\\PersonDate\\Roster.dat"));
oos.writeObject(object);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//反序列化类
class Deserialization {
public Deserialization() { }
public Object deserialize() {
Object object=null;
//创建对象输入流
ObjectInputStream ois = null;
//操作流
try {
//反序列化,把对象从硬盘读出到内存中
ois = new ObjectInputStream(new FileInputStream("D:\\PersonDate\\Roster.dat"));
object = (Object) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return object;
}
}
//人类
class Person implements Serializable {
//序列化版本号
private static final long serialVersionUID = 20220611L;
//属性
private int Id;
private String name;
//构造方法
public Person(int Id,String name) {
this.Id = Id;
this.name = name;
}
//修改方法
public void setName(String name) {
this.name = name;
}
//输出信息方法
@Override
public String toString() {
return "Person{" +
"Id=" + Id +
", name='" + name + '\'' +
'}';
}
}
/*运行结果:
Person{Id=1001, name='张三'}
请输入新名字
李四
修改成功
Person{Id=1001, name='李四'}
保存成功
程序退出
*/
第二次运行:
//代码同第一次运行,但不将反序列化语句注释掉,使得反序列化功能执行
--------代码同上--------
/*运行结果:
从硬盘读入数据
Person{Id=1001, name='李四'}
请输入新名字
*/
总结
如示例代码所示,使用序列化与反序列化可以实现数据的更新与保存。