保存对象引用:
基于前面的例子,我们现在假设每个Manager 都拥有一个秘书Employee,而且一个或者多个Manager 拥有的是同一个秘书,我们不希望保存对象流时出现这种状况, 2个manager 一个秘书employee ,保存时,一共保存了3个employee。这样的话当希望对秘书employee 作出修改时,必须找出其他拷贝对象,再逐一修改。
我们希望做的是只保存和恢复秘书的一个拷贝,磁盘上的对象与内存中的对象布局完全一致。称其为 持久性 。想要达到这种效果,java 使用序列化的 方法,也就是 对象序列化:
1 所有保存到磁盘的对象都有一个序列
2 当向磁盘存储一个对象时,先检查是否有相同的对象存在
3 如果有相同对象,就只需要写入 已经存储对象序列号。如果没有,写入对象数据,生成序列号。
看下例子: 当修改秘书employee 时,manager 中引用的 employee 同样发生改变
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);
Employee harry = new Employee("harry", 5000, 1985, 8, 21);
boss.setBonus(5000);
boss.setSecretary(harry);
Employee[] staff = new Employee[3];
staff[0] = boss;
staff[1] = harry;
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();
newStaff[1].raiseSalary(10);
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;
}
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;
private Employee secretary ;
public Manager(String n, double s, int year, int month, int day) {
super(n, s, year, month, day);
secretary = null;
}
public String toString() {
return super.toString() + "bonus=" + bonus+"-------secretary's salary = "+secretary.getSalary();
}
public void setSecretary(Employee s) {
this.secretary = s;
}
public double getSalary() {
double baseSalay = super.getSalary();
return baseSalay + bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
}
输出:
twelve.Managername=carl c---salary=8000.0bonus=5000.0-------secretary's salary = 5500.0
twelve.Employeename=harry---salary=5500.0
twelve.Employeename=tony---salary=4000.0