Thinking in java 琐碎知识点之 I/O流 、对象序列化(八)

2014-11-23 21:43:47 · 作者: · 浏览: 34
ublic Person(){ System.out.println("Person的无参构造器"); } public Person(String name ,int age){ System.out.println("Person的有参构造器"); this.age=age; this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } import java.io.Serializable; public class Teacher implements Serializable { private String name; private Person student;//Teacher类持有的Person类应该是可序列化的 public Teacher(String name,Person student){ System.out.println("Teacher的有参构造器"); this.student=student; this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person getStudent() { return student; } public void setStudent(Person student) { this.student = student; } } import java.io.*; public class SerializeMutable { public static void main(String[] args) { ObjectOutputStream oos=null; ObjectInputStream ois=null; try { oos=new ObjectOutputStream(new FileOutputStream("F:\\objecttest.txt")); Person p=new Person("zpc", 24); oos.writeObject(p); p.setName("niao鹏"); //第二次写同样的对象时只是输出序列化编号 oos.writeObject(p); ois=new ObjectInputStream(new FileInputStream("F:\\objecttest.txt")); Person p1=(Person) ois.readObject(); //实际得到的是和p1同样的对象 Person p2=(Person) ois.readObject(); System.out.println("p1=p2 "+(p1==p2)); System.out.println("p2.getName():"+p2.getName()); System.out.println("==================================="); Person perstu=new Person("云翔", 15); Teacher t1=new Teacher("马老师",perstu); Teacher t2=new Teacher("周老师",perstu); oos.writeObject(perstu); oos.writeObject(t1); oos.writeObject(t2); Person pperstu1=(Person)ois.readObject(); Teacher tt1=(Teacher)ois.readObject(); Teacher tt2=(Teacher)ois.readObject(); System.out.println("tt1.getStudent()==p "+(tt1.getStudent()==pperstu1)); System.out.println("tt2.getStudent()==p "+(tt2.getStudent()==pperstu1)); System.out.println(tt2.getStudent().getName()); oos.writeObject(perstu); Person pperstu2=(Person)ois.readObject(); System.out.println("pperstu2==pperstu1 "+(pperstu2==pperstu1)); System.out.println(pperstu1.getName()); System.out.println(pperstu2.getName()); //下面的语句报错,再次证明了写入、读出对象要一致 // Person pperstu3=(Person)ois.readObject(); // System.out.println(pperstu3.getName()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }catch(ClassNotFoundException e){ e.printStackTrace(); } } }
13、自定义序列化
在属性前面加上transient关键字,可以指定Java序列化时无需理会该属性值,由于transient修饰的属性将被完全隔离在序列化机制外,
这会导致在反序列化恢复Java对象时无法取得该属性值。
实现自定义序列化要重写类的如下方法:
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException,ClassNotFoundException;


还有种更彻底的序列化机制可以在序列化某对象时替换该对象,此种情况下应为序列化类提供如下特殊方法:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
Java的序列化机制保证在序列化某个对象之前,先调用对象的writeReplace()方法,如果该方法