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); } }