java序列化总结

1.Serializable接口

只是一个表识接口,仅仅是告诉jvm这是一个可以序列化的接口。


2.serialVersionUID

只要这个UID的值不变,在序列化的版本中增加属性或者减少属性就不会报错;否则当版本变更后,再反序列会报错;
如果自己不定义,每次在编译的时候,编译器会自动生成一个值,但是不能保证每次编译时的值都一样,所以务必自己定义!

 

3.readResolve、readObject、writeReplace、writeObject接口

 

public class FooImpl implements java.io.Serializable{    
    private String message;    
   
    public String getFoo() {            
        return message;    
    }    
   
    public void setMessage(String message) {    
        this.message = message;    
    }    
   
    private void writeObject(java.io.ObjectOutputStream out) throws IOException {    
        System.out.println("writeObject invoked");    
        out.writeObject(this.message == null ? "hohohahaha" : this.message);    
    }    
   
    private void readObject(java.io.ObjectInputStream in) throws IOException,    
            ClassNotFoundException {    
        System.out.println("readObject invoked");    
        this.message = (String) in.readObject();    
    }    
   
    private Object writeReplace() throws ObjectStreamException {    
        System.out.println("writeReplace invoked");    
        return this;    
    }    
   
    private Object readResolve() throws ObjectStreamException {    
        System.out.println("readResolve invoked");    
        return this;    
    }    
   
    public Object serialize() throws IOException, ClassNotFoundException {    
        ByteArrayOutputStream baos = new ByteArrayOutputStream();    
        ObjectOutputStream oos = new ObjectOutputStream(baos);    
        oos.writeObject(this);    
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());    
        ObjectInputStream ois = new ObjectInputStream(bais);    
        return ois.readObject();    
    }    
         public static void main(String[] args) throws IOException,     
              ClassNotFoundException {    
                  FooImpl fooimpl = new FooImpl();    
                  fooimpl.serialize();    
    }    
}   

 

我们运行这段代码看到的debug信息:
writeReplace invoked (序列化时调用)
writeObject invoked (序列化时调用)
readObject invoked (反序列化时调用)
readResolve invoked(反序列化时调用)

4.Externalizable

Externalizable 是一个有实际方法需要实现的interface,包括writeExternal和readExternal,是Serializable接口的子接口:

  1.    public class FooImpl implements java.io.Externalizable {   
  2.     private String message;   
  3.   
  4.     public String getFoo() {   
  5.         return message;   
  6.     }   
  7.   
  8.     public void setMessage(String message) {   
  9.         this.message = message;   
  10.     }   
  11.   
  12.     private Object writeReplace() throws ObjectStreamException {   
  13.         System.out.println("writeReplace invoked");   
  14.         return this;   
  15.     }   
  16.   
  17.     private Object readResolve() throws ObjectStreamException {   
  18.         System.out.println("readResolve invoked");   
  19.         return this;   
  20.     }   
  21.   
  22.     public Object serialize() throws IOException, ClassNotFoundException {   
  23.         ByteArrayOutputStream baos = new ByteArrayOutputStream();   
  24.         ObjectOutputStream oos = new ObjectOutputStream(baos);   
  25.         oos.writeObject(this);   
  26.         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());   
  27.         ObjectInputStream ois = new ObjectInputStream(bais);   
  28.         return ois.readObject();   
  29.     }   
  30.   
  31.     public void readExternal(ObjectInput arg0) throws IOException,   
  32.             ClassNotFoundException {   
  33.         System.out.println("readExternal invoked");   
  34.         Object obj = arg0.readObject();        
  35.     }   
  36.   
  37.     public void writeExternal(ObjectOutput arg0) throws IOException {   
  38.         System.out.println("writeExternal invoked");   
  39.         arg0.writeObject("Hello world");   
  40.     }   
  41.          public static void main(String[] args) throws IOException,    
  42.               ClassNotFoundException {   
  43.                   FooImpl fooimpl = new FooImpl();   
  44.                   fooimpl.serialize();   
  45.     }   
  46. }  

我们运行这段代码看到的debug信息:
writeReplace invoked
writeExternal invoked
readExternal invoked
readResolve invoked
在此writeExternal 和readExternal 的作用与writeObject和readObject 一样.

最后,当我们同时实现了两个interface的时候,JVM只运行Externalizable 接口里面的writeExternal 和readExternal 方法对序列化内容进行处理.
需要注意的是:Serializable是一个真正的mark interface,
writeObject,readObject, writeReplace,readResolve是直接与JVM通信,告诉JVM序列化的内容.

你可能感兴趣的:(java,jvm)