为什么实现Serializbale接口就能够进行序列化?
阅读原文时间:2023年07月16日阅读:1

从所周知,Serializbale接口是个空的接口,并没有定义任何方法。那么问题来了,为什么需要序列化的接口只要实现Serializbale接口就能够进行序列化?

这要从序列化过程的源码说起。举个例子这里有个可序列化的Parent类,然后我们用一个TestSeri类对其序列化。

public class Parent implements Serializable {

private static final long serialVersionUID = 1234L;

public Parent1(String name,int age){  
    this.name = name;  
    this.age = age;  
}

private String name;  
private int age;

public String toString(){  
    return "Parent:"+name+" "+age;  
}

}

public class TestSeri {

public static  void seri(Parent parent){  
    try {  
        FileOutputStream fo = new FileOutputStream("src/est.txt");  
        ObjectOutputStream oos = new ObjectOutputStream(fo);  
        oos.writeObject(parent);  
        oos.flush();  
        oos.close();  
    } catch (Exception e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }  
}

public static void main(String\[\] args){  
    Parent parent = new Parent("ouym",24);  
    seri(parent);

}

序列话的过程主要有三步:

(1)新建文件输出流用来指定一个位置存储序列化的内容。

(2)新建一个ObjectOutputStream对象oos

(3)序列化:调用writeObject(parent)方法。

关键看第三部writeObject的内部实现过程:

public final void writeObject(Object obj) throws IOException {
//省略部分代码
try {
// 调用writeObject0()方法序列化
writeObject0(obj, false);
} catch (IOException ex) {
if (depth == 0) {
writeFatalException(ex);
}
throw ex;
}
}

可见writeObject方法的主要实现过程交给了writeObject0(obj,false)方法。

private void writeObject0(Object obj, boolean unshared)
throws IOException
{
// 一些省略代码
try {
// 一些省略代码,其他的细节我们不深入
// remaining cases
if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
writeEnum((Enum) obj, desc, unshared);
} else if (obj instanceof Serializable) {
// 被序列化对象实现了Serializable接口
writeOrdinaryObject(obj, desc, unshared);
} else {
if (extendedDebugInfo) {
throw new NotSerializableException(
cl.getName() + "\n" + debugInfoStack.toString());
} else {
throw new NotSerializableException(cl.getName());
}
}
} finally {
depth--;
bout.setBlockDataMode(oldMode);
}
}

从上述代码第8行开始,我们知道String,数组和枚举类型可以直接序列化(不难猜出String和Enum类实现了Serializbale接口)。若不是上述三种类型的话,接下来重点看14到16行代码,如果对象实现了Serializbale接口的话,就用writeOrdinaryObject()方法进行序列化操作。这里我们就不看writeOrdinaryObject方法的细节了,因为我们已经找到了标题的答案。Serializable接口这是一个标识,告诉程序所有实现了他的对象都可以进行序列化。

更多关于序列化的详情推荐大神博客:http://www.importnew.com/24490.html