目录
- 一、什么是serialVersionUID
 - 二、创建一个serialVersionUID
 - 三、使用 serialVersionUID
 - 3.1 序列化实例程序
 - 3.2 反序列化实例程序
 - 3.3 serialVersionUID不同的情况下进行序列话和反序列化
 - 3.4 能不能不提供serialVersionUID?
 
一、什么是serialVersionUID
SerialVersionUID属性是用于序列化/反序列化可序列化类的对象的标识符,我们使用serialVersionUID属性来记住可序列化类的版本,以验证加载的类和序列化对象是否兼容。如果接收方为对象加载的类serialVersionUID与相应发送方的类不同,则反序列化将导致 InvalidClassException。
备注:不同类的serialVersionUID属性是独立的。因此,不同的类没有必要具有唯一的值。
二、创建一个serialVersionUID
首先创建一个可序列化的类并声明一个serialVersionUID标识符:
public class Test implements Serializable {
    private static final long serialVersionUID = 1L;
    public String name;
    public String password;
}
 
三、使用 serialVersionUID
下来我们创建两个类,一个用以序列化,另一个用以反序列化。
3.1 序列化实例程序
public class SerializationUtility {
    public static void main(String[] args) {
        Test serial= new Test ();
        serial.name= "serial123";
        serial.password= "serial369";
        String serializedObj = serializeObjectToString(serial);
 
        System.out.println("Serialized Test object to string:");
        System.out.println(serializedObj);
    }
    public static String serializeObjectToString(Serializable o) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(o);
        oos.close();
        return Base64.getEncoder().encodeToString(baos.toByteArray());
    }
}
 
运行SerializationUtility,将Test对象保存(序列化)到String实例中,并使用Base64对字节进行编码,得到下面的结果:
 
3.2 反序列化实例程序
public class DeserializationUtility {
 
    public static void main(String[] args) {
 
        String serializedObj = ... // 省略
        System.out.println( "Deserializing Test...");
 
        Test deserializedObj = (Test) deSerializeObjectFromString( serializedObj);
 
         System.out.println( "Headphone port of Test: "+ deserializedObj.name);
        System.out.println(  "Thunderbolt port of Test: " + deserializedObj.password);
    }
 
    public static Object deSerializeObjectFromString(String s)
      throws IOException, ClassNotFoundException {
  
        byte[] data = Base64.getDecoder().decode(s);
        ObjectInputStream ois = new ObjectInputStream(
          new ByteArrayInputStream(data));
        Object o = ois.readObject();
        ois.close();
        return o;
    }
}
 
使用上面序列化的 String 作为反序列化方法的参数,运行DeserializationUtility,给定的String 重新组装(反序列化) Test对象,得到下面的结果:
 
3.3 serialVersionUID不同的情况下进行序列话和反序列化
我们随便改一下前面 Test 的serialVersionUID,比如这样子:
public class Test implements Serializable {
    private static final long serialVersionUID = 2L;
    public String name;
    public String password;
}
 
然后运行反序列化程序 DeserializationUtility ,得到下面的结果:

为什么会这样?
因为我们通过更改类的serialVersionUID,修改了它的版本/状态。结果反序列化的时候没有找到兼容的类,抛出了InvalidClassException。
3.4 能不能不提供serialVersionUID?
如果Serialized类中未提供serialVersionUID,JVM 将自动生成一个。但是,最好提供serialVersionUID值并在类更改后更新它,以便我们可以控制序列化/反序列化过程。
这种情况下如果类的一些更改可能会破坏序列化兼容性。



















