Java对象序列化

1.说明

所有分布式应用常常需要跨平台,跨网络,因此要求所有传的参数、返回值都必须实现序列化。而对象序列化包含序列化和反序列化二部分,序列化是把Java对象转换为字节序列的过程,反序列化是把字节序列恢复为Java对象的过程。

2.用途

对象序列化主要有二种用途,一个是把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中,也叫持久化对象;另一个是在网络上传送对象的字节序列,也叫网络传输对象。

3.实现

序列化需要实现Serializable或Externalizable接口。序列化过程中ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。反序列化过程中ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

4.示例

要被序列化的实体类

public class Emp implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static String name;
	private int age;
	private transient String dept;
	public Emp() {
		super();
		
	}
	public Emp(String name, int age, String dept) {
		super();
		Emp.name = name;
		this.age = age;
		this.dept = dept;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		Emp.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getDept() {
		return dept;
	}
	public void setDept(String dept) {
		this.dept = dept;
	}
	@Override
	public String toString() {
		return "Emp [name=" + name + ", age=" + age + ", dept=" + dept + "]";
	}

该实体类中实现了Serializable接口,并生了默认的serialVersionUID,而且name属性被修饰为static,dept属性添加了transient关键字。

public class TestSerialization {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		/*
		 * 序列化保存对象
		 */
		FileOutputStream foStream = new FileOutputStream("f:"+File.separator+"b.txt");
		ObjectOutputStream oos = new ObjectOutputStream(foStream);
		oos.writeObject(new Emp("张三", 13, "机械部"));
		oos.writeObject(new Emp("李四", 23, "工程部"));
		oos.close();
		/*
		 * 序列化读取对象
		 */
		FileInputStream fis = new FileInputStream("f:"+File.separator+"b.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		Emp emp = (Emp)ois.readObject();
		Emp emp1 = (Emp)ois.readObject();
		System.out.println(emp);
		System.out.println(emp1);
		ois.close();
	}

在该测试类中实现了序列化和反序列的过程,结果如下图所示:

从结果中可以得出结论,被static修饰的变量是不参与序列化的,而被transient修饰的变量dept也没有被序列化,其实有时候,我们并不希望出现递归序列化,或是某个存敏感信息(如银行密码)的属性不被序列化,我们就可通过transient关键字修饰该属性来阻止被序列化。

现在将实体类的无参构造添加如下代码

public Emp() {
		System.out.println("无参构造...");		
	}

而测试类改变代码为

public class TestSerialization {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		/*
		 * 序列化保存对象
		 */
		FileOutputStream foStream = new FileOutputStream("f:"+File.separator+"b.txt");
		ObjectOutputStream oos = new ObjectOutputStream(foStream);
		oos.writeObject(new Emp("张三", 13, "机械部"));
		oos.writeObject(new Emp("李四", 23, "工程部"));
		oos.close();
		/*
		 * 序列化读取对象
		 */
		FileInputStream fis = new FileInputStream("f:"+File.separator+"b.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		Object emp = ois.readObject();
		Object emp1 = ois.readObject();
		System.out.println(emp);
		System.out.println(emp1);
		ois.close();
	}

}

结果显示为

结果没有打印“无参构造...”,说明反序列化机制无需通过构造器来初始Java对象。





猜你喜欢

转载自blog.csdn.net/chenbingbing111/article/details/79826906
今日推荐