今天工作时发现一个序列化的问题:

基类(类A)没有实现序列化接口(Serializable),而子类(类B)实现了序列化接口,对子类对像进行序列化,然后反序列化,这里发现反序化后的对象在基类的中的很多属性都变成了null.
 
  
  1. public abstract class FirstLevel {//基类  
  2.     private Map map;  
  3.    
  4.     public FirstLevel(){  
  5.      System.out.println("first");  
  6.     }  
  7.     protected void init(){  
  8.        map = new HashMap(0);  
  9.     }  
  10.       
  11.     public Map getMap() {  
  12.        return map;  
  13.     }  
  14.     public void setMap(Map map) {  
  15.        this.map = map;  
  16.     }  
  17. }  
  18.    
  19. public class SecondLevel extends FirstLevel implements Serializable{  
  20.     public SecondLevel(){  
  21.        init();  
  22.        System.out.println("second");  
  23.     }  
  24. }  
  25.    
  26. public class Test {  
  27.     public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{  
  28.        System.out.println("before:");  
  29.        SecondLevel before = new SecondLevel();  
  30.        HashMap a = new HashMap();  
  31.        a.put("key""guojje");  
  32.        before.setMap(a);   
  33.          
  34.        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:\\t.txt"));  
  35.        oos.writeObject(before);  
  36.        oos.close();  
  37.        System.out.println("after:");  
  38.        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:\\t.txt"));  
  39.        SecondLevel after = (SecondLevel)ois.readObject();  
  40.        ois.close();  
  41.        System.out.println(after.getMap());  
  42.          
  43.     }  
  44. }  
 
 
输出:
before:
first
second
after:
first
null
这里map属性我是赋过值的,为什么变成NULL了吗,另外创建对像时调用FirstLevel ,
SecondLevel 两个构造函数,但是反序列化时也调用了FirstLevel的构造函数(理论上序列化是不用调用构造函数的)。
 
看来没有实现序列化接口的基类并没有真正的序列化与反序列化,而是借用其构造函数来实现对象的初始化(可以肯定得不到序列化时的属性值),因为FirstLevel的构造函数并没有初始化MAP成员,所以返回NULL。
 
查阅一些资料,JDK文档上这么说:
序列化操作不会写出没有实现 java.io.Serializable 接口的任何对象的字段。不可序列化的 Object 的子类可以是可序列化的。在此情况下,不可序列化的类必须有一个无参数构造方法,以便允许初始化其字段。在此情况下,子类负责保存和还原不可序列化的类的状态。
 
果然如此。
 
又一个问题(A>B表示B继承于A):
   A > B (Serializable)> C > D(Serializable) > E
反序列化E对象,会调用哪几个构造函数呢,答案是一个, A的. 因为其他类都从基类继承了Serializable接口,而A没有.
 
下一个问题,如果想完全的序列化E对象怎么办:
   在子类中(B,C,D,E都可)来序例化A类的成员,然后赋值上去,别无他法.