序列化中关于继承

  • 实验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();
        }
    }
}

结论:

  1. 如果Super类包含需要序列化的primitive类型变量,应该实现writeObject()和readObject()方法,并在里面分别调用ObjectOutputStream.defaultWriteObject()和ObjectInputStream.defaultReadObject()方法。
  2. writeObject()和readObject()的修饰符、返回类型、参数必须符合规定,即必须是如下格式:
    private void writeObject(ObjectOutputStream o) throws...;
    private void readObject(ObjectInputStream o) throws...;
    否则这两个方法将不会被调用。
  3. 如果父类实现了Serializable接口,子类将自动得到可序列化特性。并且序列化子类时,父类的writeObject()和readObject()将得到调用。换言之,在序列化子类之前,父类将会自动被序列化。
  4. 子类实例化时候,会实例化父类
  • 实验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();
        }
    }
}

结论:

  1. 当父类没有实现Serializable接口的前提下,序列化子类时父类将不会被自动序列化。而反序列化子类时,父类的无参数构造方法将会被调用。
  2. 如果想在序列化子类的同时也自动序列化父类中的字段,必须在子类的writeObject()和readObject()中相应实现。

转载于:https://my.oschina.net/winchell/blog/805602

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值