序列化和反序列化
- 对象序列化
- 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化
- 序列化和反序列化
- 序列化是将内存中的对象保存到文件中
- 反序列化是将对象从文件加载到内存中
- 如果一个对象被序列化,那么引用这个对象的其他对象也将被序列化
- 如果一个对象被反序列化,那么引用这个对象的其他对象也将被恢复
- 一个类如果想要被序列化,则应该实现java.io.Serializable接口,
- 该接口中没有任何方法,只是一个标识性接口(Marker Interface),
- 当一个类实现了Serializable接口,就表示这个类的对象可以被序列化
- 一个对象被序列化,只能保存非静态成员变量,其他的都不能保存
- 静态成员变量不能保存的原因是,静态成员变量不属于对象是属于类本身
- 如果成员变量是一个对象,那么这个对象的成员变量也会被保存
- 一个对象中的对象不可以被序列化,那么这个对象被序列化将会失败,
- 并且抛出NotSerializableException
- 如果这个对象必须被序列化,我们可以把对象中的对象标记为transient(瞬时的)
- 如果一个类可以被序列化,那么所有子类也可以被序列化
- package com.itlwc;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- /**
- * Java自身实现序列化和反序列化
- */
- public class Test {
- public static void main(String[] args) throws Exception {
- Person p1 = new Person("lwc", 18, "陕西");
- Person p2 = new Person("tom", 19, "河南");
- Person p3 = new Person("cat", 20, "北京");
- // 序列化
- FileOutputStream fos = new FileOutputStream("person.txt");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(p1);
- oos.writeObject(p2);
- oos.writeObject(p3);
- // 反序列化
- FileInputStream fis = new FileInputStream("person.txt");
- ObjectInputStream ois = new ObjectInputStream(fis);
- for (int i = 0; i < 3; i++) {
- Person p = (Person) ois.readObject();// 把对象写入文件中
- System.out.println(p.name + "," + p.age + "," + p.address);
- }
- oos.close();
- ois.close();
- }
- }
- // 要想使某个类序列化,这个类必须实现Serializable接口
- class Person implements Serializable {
- private static final long serialVersionUID = -7147436129983998671L;
- // 被static,transient修饰的变量不会被保存到文件
- static int number;
- String name;
- int age;
- transient String address;
- public Person(String name, int age, String address) {
- super();
- this.name = name;
- this.age = age;
- this.address = address;
- }
- }
- package com.itlwc;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- /**
- * 自定定义实现序列化和反序列化
- */
- public class Test {
- public static void main(String[] args) throws Exception {
- Person p1 = new Person("lwc", 18, "陕西");
- Person p2 = new Person("tom", 19, "河南");
- Person p3 = new Person("cat", 20, "北京");
- FileOutputStream fos = new FileOutputStream("person.txt");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(p1);
- oos.writeObject(p2);
- oos.writeObject(p3);
- FileInputStream fis = new FileInputStream("person.txt");
- ObjectInputStream ois = new ObjectInputStream(fis);
- for (int i = 0; i < 3; i++) {
- Person p = (Person) ois.readObject();// 把对象写入文件中
- System.out.println(p.name + "," + p.age + "," + p.address);
- }
- oos.close();
- ois.close();
- }
- }
- class Person implements Serializable {
- private static final long serialVersionUID = -7147436129983998671L;
- static int number;
- String name;
- int age;
- transient String address;
- public Person(String name, int age, String address) {
- super();
- this.name = name;
- this.age = age;
- this.address = address;
- }
- /*
- * 如果序列化/反序列化的类自身定义了writeObject()和readObject(),
- * 那么我们可以更底层方式控制序列化/反序列化的过程,
- * writeObject()和readObject()在序列化/反序列化的时候将自动调用
- * 如果不在writeObject()和readObject()中定义代码,只有成员变量保存到文件中,值不保存
- * 要想值也保存,必须在writeObject()和readObject()中自定义代码
- */
- private void writeObject(java.io.ObjectOutputStream out) throws Exception {
- out.writeUTF(name);
- out.writeInt(age);
- }
- private void readObject(java.io.ObjectInputStream in) throws Exception {
- name = in.readUTF();
- age = in.readInt();
- }
- }