java中的序列化

63 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路.

本文档由该视频整理:视频链接

什么是序列化和反序列化

序列化: Serializable将java对象存储到文件中,将java对象的状态保存下来的过程。 反序列化: DeSerializable将硬盘上的数据重新恢复到内存当中,恢复成java对象。

序列化的要求

  1. 参与序列化和反序列化的对象,必须实现Serializable接口。
  2. 注意:通过源代码发现,Serializable接口只是一个标志接口;
public interface Serializable{
}

Serializable接口的作用

起到标识的作用,标志的作用,java虚拟机看到这个类实现了这个接口,会为这个类生成一个序列化版本号。

序列化和反序列化的实现

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Test {

	public static void main(String[] args) {
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;
		try {
			// 创建java对象
			Student s = new Student("张三");
			// 序列化
			oos = new ObjectOutputStream(new FileOutputStream("文件路径"));
			// 序列化对象
			oos.writeObject(s);
			// 刷新
			oos.flush();

			// 反序列化
			ois = new ObjectInputStream(new FileInputStream("文件路径"));
			Object obj = ois.readObject();
			System.out.println(obj);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (oos != null) {
				// 关闭
				try {
					oos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ois != null) {
				try {
					ois.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

class Student implements Serializable {
	private String name;

	public Student(String name) {
		super();
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}

}

transient关键字

如果不希望对象的某个属性不参与序列化操作,可以为该属性加上transient关键字修饰

java语言中是采用什么机制来区分类的?

第一:首先通过类名进行比对,如果类名不一样,肯定不是同一个类。 第二:如果类名一样,再怎么进行类的区别?靠序列化版本号进行区分。

自动生成序列化版本号有什么缺陷?

对于实现Serializable接口的类,一旦代码确定之后,不能进行后续的修改,因为只要修改,必然会重新编译,此时会生成全新的序列化版本号,这个时候java虚拟机会认为这是一个全新的类。(这样就不好了!)

手动编写序列化版本号

  1. 好处:凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。
  2. 在类中增加该属性即可:
private static final long serialVersionUID