还是上一篇日志的测试代码:
class="java" name="code">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