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