java_croe 学习笔记之对象流

一、串行化的概念和目的

1.什么是串行化

            对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行化(Serialization) 。串行化的主要任务是写出对象实例变量的数值。如果交量是另一对象的引用,则引用的对象也要串行化。这个过程是递归的,串行化可能要涉及一个复杂树结构的单行化,包括原有对象、对象的对象、对象的对象的对象等等。对象所有权的层次结构称为图表(graph)。

2.串行化的目的

            Java对象的单行化的目标是为Java的运行环境提供一组特性,如下所示:

1)       尽量保持对象串行化的简单扼要 ,但要提供一种途径使其可根据开发者的要求进行扩展或定制。

2)       串行化机制应严格遵守Java的对象模型 。对象的串行化状态中应该存有所有的关于种类的安全特性的信息。

3)       对象的串行化机制应支持Java的对象持续性。

4)       对象的串行化机制应有足够的 可扩展能力以支持对象的远程方法调用(RMI)。

5)       对象串行化应允许对象定义自身 的格式即其自身的数据流表示形式,可外部化接口来完成这项功能。

二、串行化方法
            从JDK1.1开始,Java语言提供了对象串行化机制 ,在java.io包中,接口Serialization用来作为实现对象串行化的工具 ,只有实现了Serialization的类的对象才可以被串行化。

            Serializable接口中没有任何的方法。当一个类声明要实现Serializable接口时,只是表明该类参加串行化协议,而不需要实现任何特殊的方法。下面我们通过实例介绍如何对对象进行串行化。 (转自http://blog.csdn.net/sodino/archive/2008/12/21/3576147.aspx

 

 

关于对象序列化和反序列化的顺序:反序列化是按照序列化的顺序进行读取的,所以反序列化的时候一定要按照序列化的顺序读取

 

 

自己写的列子

package twelve;

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;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @Title ObjectFileTest.java
 * @description TODO
 * @author qinpeng
 * @date Aug 19, 2009 10:40:49 PM
 */
public class ObjectFileTest {

	public static void main(String[] args) {

		ObjectOutputStream out = null;
		ObjectInputStream in = null;

		Manager boss = new Manager("carl c", 8000, 1987, 12, 15);
		boss.setBonus(5000);

		Employee[] staff = new Employee[3];
		staff[0] = boss;
		staff[1] = new Employee("harry", 5000, 1985, 8, 21);
		staff[2] = new Employee("tony", 4000, 1986, 6, 12);

		try {
			try {
				out = new ObjectOutputStream(new FileOutputStream(
						"employee.dat"));
				out.writeObject(staff);
			} finally {
				if (out != null) {
					out.close();
				}
			}
		} catch (FileNotFoundException foundE) {
			foundE.printStackTrace();
			System.err.print("employee.dat  is not found");
		} catch (IOException ioE) {
			ioE.printStackTrace();
			System.err.print("IOException of main");
		}

		try {
			try {
				in = new ObjectInputStream(new FileInputStream("employee.dat"));
				Employee[] newStaff = (Employee[]) in.readObject();
				for (Employee e : newStaff) {
					System.out.println(e);
				}
			} finally {
				if (in != null) {
					in.close();
				}
			}

		} catch (ClassNotFoundException classE) {
			classE.printStackTrace();
			System.err.print("employee.dat  is not found");
		} catch (FileNotFoundException foundE) {
			foundE.printStackTrace();
			System.err.print("employee.dat  is not found");
		} catch (IOException ioE) {
			ioE.printStackTrace();
			System.err.print("IOException of main");
		}
	}

}

class Employee implements Serializable {

	private  String name;
	//private transient String name;
	private double salary;
	private Date hireDay;

	public Employee() {
	}

	public Employee(String n, double s, int year, int month, int day) {
		name = n;
		salary = s;
		GregorianCalendar claendar = new GregorianCalendar(year, month - 1, day);
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}

	public String toString() {

		return getClass().getName() + "name=" + name + "---salary=" + salary
				+ "---hirDay=" + hireDay;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public Date getHireDay() {
		return hireDay;
	}

	public void setHireDay(Date hireDay) {
		this.hireDay = hireDay;
	}
}

class Manager extends Employee {

	private double bonus;

	public Manager(String n, double s, int year, int month, int day) {
		super(n, s, year, month, day);
	}

	public String toString() {

		return super.toString() + "bonus=" + bonus;
	}

	public double getSalary() {
		double baseSalay = super.getSalary();
		return baseSalay + bonus;
	}

	public double getBonus() {
		return bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}

}

   这里当域没有用 transient  修饰的时候,该域作为对象的内容被保存起来。输出结果如下:

 

   twelve.Managername=carl c---salary=8000.0bonus=5000.0
   twelve.Employeename=harry---salary=5000.0
   twelve.Employeename=tony---salary=4000.0

 

  如果域 name 使用 transient   该域将不会进行保存

 

class Employee implements Serializable {

	//private  String name;
	private transient String name;
	private double salary;
	private Date hireDay;
........

 结果如下:

 

twelve.Managername=null---salary=8000.0bonus=5000.0
twelve.Employeename=null---salary=5000.0
twelve.Employeename=null---salary=4000.0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值