- 实验1
package com.youchuang.tigers;
import com.sun.xml.internal.ws.developer.Serialization;
import java.io.*;
public class Tiger3 {
static class Sub extends Super {
private String name;
public Sub(int id, int uid, String name) {
super(id, uid);
this.name = name;
}
public String toString() {
return "Tiger3$Sub:(" + super.toString() + "," + name + ")";
}
private void writeObject(ObjectOutputStream oos) throws IOException {
System.out.println("Sub.writeObject()");
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
System.out.println("Sub.readObject()");
ois.defaultReadObject();
}
}
static class Super implements Serializable {
private int id;
private transient int uid;
public Super(int id, int uid) {
this.id = id;
this.uid = uid;
}
private static final long serialVersionUID = 1L;
private void writeObject(ObjectOutputStream oos) throws IOException {
System.out.println("Super.writeObject()");
oos.defaultWriteObject();
oos.writeInt(uid);
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
System.out.println("Super.readObject()");
ois.defaultReadObject();
uid = ois.readInt();
}
public String toString() {
return "Tiger3$Super:(" + id + "," + uid + ")";
}
}
public static void main(String[] args) {
// Tiger3.Super sup = new Tiger3.Super(55, 1000);
Tiger3.Sub sub = new Tiger3.Sub(12, 100, "sub");
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Tiger3$Super.tmp"));
// oos.writeObject(sup);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Tiger3$Super.tmp"));
// sup = (Tiger3.Super) ois.readObject();
// System.out.println(sup);
oos = new ObjectOutputStream(new FileOutputStream("D:\\Tiger3$Sub.tmp"));
oos.writeObject(sub);
ois = new ObjectInputStream(new FileInputStream("D:\\Tiger3$Sub.tmp"));
sub = (Tiger3.Sub) ois.readObject();
System.out.println(sub);
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
}
结论:
- 如果Super类包含需要序列化的primitive类型变量,应该实现writeObject()和readObject()方法,并在里面分别调用ObjectOutputStream.defaultWriteObject()和ObjectInputStream.defaultReadObject()方法。
- writeObject()和readObject()的修饰符、返回类型、参数必须符合规定,即必须是如下格式:
private void writeObject(ObjectOutputStream o) throws...;
private void readObject(ObjectInputStream o) throws...;
否则这两个方法将不会被调用。 - 如果父类实现了Serializable接口,子类将自动得到可序列化特性。并且序列化子类时,父类的writeObject()和readObject()将得到调用。换言之,在序列化子类之前,父类将会自动被序列化。
- 子类实例化时候,会实例化父类
- 实验2
package com.youchuang.tigers;
import java.io.*;
/**
* Created by Winchell on 2016/12/14 0014.
*/
public class Tiger4 {
static class Super {
private String name;
public Super(String name) {
this.name = name;
}
public Super() {
this.name = "default";
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return "Tiger4$Super:(" + name + ")";
}
}
static class Sub extends Super implements Serializable {
private String name;
Sub (String superName, String name) {
super(superName);
this.name = name;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(super.getName());
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
super.setName((String) ois.readObject());
}
public String toString() {
return "Tiger4$Sub:("+ super.toString() + "," + name + ")";
}
}
public static void main(String[] args) {
Sub sub = new Sub("super","sub");
try {
System.out.println("序列化之前:" + sub);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\Tiger4$Sub.tmp"));
oos.writeObject(sub);
System.out.println("序列化之后:" + sub);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\Tiger4$Sub.tmp"));
sub = (Sub) ois.readObject();
System.out.println("反序列化之后:" + sub);
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
}
结论:
- 当父类没有实现Serializable接口的前提下,序列化子类时父类将不会被自动序列化。而反序列化子类时,父类的无参数构造方法将会被调用。
- 如果想在序列化子类的同时也自动序列化父类中的字段,必须在子类的writeObject()和readObject()中相应实现。