有关Java序列化(二)
程序员文章站
2022-05-14 17:17:57
...
还是上一篇日志的测试代码:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = -842029427676826563L;
public static String name = "Tony";
private int age;
private transient int workDay = 5;
private String fClub = "Arsenal";
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getWorkDay() {
return workDay;
}
public void setWorkDay(int workDay) {
this.workDay = workDay;
}
public String getfClub() {
return fClub;
}
public void setfClub(String fClub) {
this.fClub = fClub;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();//执行默认的序列化机制
out.writeInt(workDay);
System.out.println("正在进行序列持久化");
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
workDay = in.readInt();
System.out.println("读取持久化对象");
}
}
主测试类代码还是一样:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Hello {
public static void main(String[] args) {
Person person = new Person();
person.setAge(26);
person.setWorkDay(7);
person.setfClub("Juventus");
try {
FileOutputStream fs = new FileOutputStream("foo.ser");
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(person);
os.close();
Person.name = "Alex";
FileInputStream in = new FileInputStream("foo.ser");
ObjectInputStream s = new ObjectInputStream(in);
Person p = (Person) s.readObject();
System.out.println("name==" + Person.name + " age==" + p.getAge()
+ " workDay==" + p.getWorkDay() + " fClub==" + p.getfClub());
} catch (Exception e) {
e.printStackTrace();
}
}
}
程序的输出为:
正在进行序列持久化 读取持久化对象 name==Alex age==26 workDay==7 fClub==Juventus
跟上一篇日志的输出就不一样了,workDay的值变成了7,而不是0了。可以看到workDay在Person类的声明还是一样,还是用transient修饰了。问题的关键是Person类里新添加的writeObject和readObject方法。
在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,如上篇日志所说,此时会忽略掉workDay字段。然后再调用writeInt()方法显式地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。
在foo.ser文件里当然也有了workDay。这里这两个方法只是实现了workDay声明中去掉transient等效的功能,当然更普遍的是想在对象序列化时进行一些额外的别的操作。
需要注意的是,writeObject()与readObject()都是private方法,那么它们是如何被调用的呢?毫无疑问,是使用反射。
参考:
http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html
上一篇: CSS3中更灵活的布局方式_html/css_WEB-ITnose
下一篇: Java基础知识小结