用户工具


java序列化的核心是用ObjectOutputStream讲一个对象变成一个二进制流保持,用ObjectInputStream读取的过程

Java序列化接口

  • 我们知道实现了Serializable接口就可以被序列化,但是其实Serializable接口并没有做任何事情,它只是一个标志
  • 如果重写了writeObject,readObject函数,那在序列化、反序列化时会调用这两个函数。按照自定义的方式序列化,反序列化
  • readObject(ObjectInputStream ois):如果这个方法存在,ObjectInputStream readObject()方法会调用该方法从流中读取对象。
  • writeObject(ObjectOutputStream oos):如果这个方法存在,ObjectOutputStream writeObject()方法会调用该方法从流中写入对象。一种普遍的用法是隐藏对象的值来保证完整性。
class c implements Serializable {

    private static final long serialVersionUID = 2087368867376448459L;
    private String s = new String("123");


    @Override
    public String toString() {
        return s;
    }

    private  void writeObject(ObjectOutputStream ois) {
        System.out.println("write");
    }
    private void readObject(ObjectInputStream ois){
        System.out.println("read");
    }
}

Java外部化接口

  • 也可以通过实现Externalizable接口的方式自定义序列化
  • Object writeReplace():如果这个方法存在,那么在序列化处理之后,该方法会被调用并将返回的对象序列化到流中。
  • Object readResolve():如果这个方法存在,那么在序列化处理之后,该方法会被调用并返回一个最终的对象给调用程序。一种使用方法是在序列化类中实现单例模式,你可以从序列化和单例中读到更多知识。
class c implements Externalizable {

    private static final long serialVersionUID = 2087368867376448459L;
    private String s = new String("123");

    public c(){}

    @Override
    public String toString() {
        return s;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        System.out.println("write");
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        System.out.println("read");
    }
}

对子类对象进行反序列化时, 如果其父类没有实现Serializable接口, 那么改父类的构造函数会被调用。

  • ObjectInputStream
    • 重要方法 readObject() # 将一个对象反序列化
  • ObjectOutputStream
    • 重要方法 writeObject() # 将一个对象序列化
  • 被序列化的对象一定要实现Serializable接口

    我们也可以用transient关键字指定一个类中个别字段不使用jvm序列化(可以选择不序列化,或自己实现该字段的序列化)

import java.io.*;


class Foo  implements Serializable{
    public String user;
    public String name;

    public Foo(String u,String n){
        super();
        this.user=u;
        this.name=n;
    }
}
public class io {
    public static void main(String args[]) throws IOException, ClassNotFoundException {

        ObjectOutputStream i = new ObjectOutputStream(new FileOutputStream("aa.bat"));
        i.writeObject(new Foo("aa","bb"));
        i.close();
        ObjectInputStream j = new ObjectInputStream(new FileInputStream("aa.bat"));
        Foo f = (Foo)j.readObject();
        j.close();
        System.out.println(f.user+" : "+f.name);

    }
}