serialVersionUID的作用
对于实现了Serializable接口的类,如果没有主动在程序中加上serialVersionUID,那么编译器会默认加上。一般情况下最好是自己加上,编译器默认的ID依赖于编译器的实现,在反序列化时,可能会报InvalidClassExceptions
。
先看java bean的代码:
1 package com.oppo.test; 2 3 import java.io.Serializable; 4 5 public class Student implements Serializable { 6 7 /** 8 * 9 */ 10 private static final long serialVersionUID = 1L; 11 private int id; 12 13 public int getId() { 14 return id; 15 } 16 17 public void setId(int id) { 18 this.id = id; 19 } 20 }
序列化的工具类:
1 import java.io.File; 2 import java.io.FileInputStream; 3 import java.io.FileOutputStream; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 7 public class UIDTester { 8 9 /** 10 * @param args 11 */ 12 public static void main(String[] args) throws Exception{ 13 // TODO Auto-generated method stub 14 15 File file = new File("out.ser"); 16 FileOutputStream fos = new FileOutputStream(file); 17 ObjectOutputStream oos = new ObjectOutputStream(fos); 18 19 SerializeMe serializeMe = new SerializeMe(1); 20 oos.writeObject(serializeMe); 21 22 FileInputStream fis = new FileInputStream(file); 23 ObjectInputStream ois = new ObjectInputStream(fis); 24 25 Student s = (Student)ois.readObject(); 26 27 System.out.println("id: " + s.getId()); 28 ois.close(); 29 } 30 31 }
显然,这段代码是对Student类的序列化和反序列化。在Student类中,添加了序列化ID serialVersionUID,需要注意的是,虽然序列化的时候并不会序列化类中的静态成员和临时成员,但对serialVersionUID是个例外,序列化时serialVersionUID会被写到输出流中,运行程序,有如下输出:
id: 1
不要删除输出文件,改变Student类中的serialVersionUID
private static final long serialVersionUID = 2L;
然后将UIDTester类中对Student类的序列化步骤注释掉,即只进行反序列化工作,运行程序:
Exception in thread "main" java.io.InvalidClassException:
程序报异常了,因为序列化是ObjectOutputStream将serialVersionUID写到文件out.ser(其实也可能写到socket中登登)中,此时为1L,在反序列化时ObjectInputStream从文件中读出serialVersionUID,发现这个UID和当前类Student版本的UID不一致,就会扔出InvalidClassException异常。
如果对类A进行序列化后,反序列化工作在网络的另一端(算得上是空间距离吧,这时候可能JVM的版本都不相同)或者时隔很久以后(算是时间距离),那么在这个距离段内,类A的成员可能会发生变化(这个真心谁也说不准),需要有一套版本机制,于是serialVersionUID应运而生。它总是检查输出流和输入流里面的对象版本是否改变了。所以,一旦Student类有所改变,我们都有责任改变它的serialVersionUID,如果不变,反序列化之后根本得不到新增的成员变量。
对于Externalizable,详情 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4094702