Serializable接口为什么需要定义serialVersionUID常量
serialVersionUID常量用于标明当前Serializable类的版本,以验证加载的类和序列化对象是否兼容。
在进行序列化时会将当前类的serialVersionUID写入到字节序列中,在反序列化时会将当前字节流中的serialVersionUID同本地对象中的serialVersionUID进行对比,如果相同则继续序列化,如果不同则失败报错。
serialVersionUID常量值默认为1L。
serialVersionUID常量用于标明当前Serializable类的版本,以验证加载的类和序列化对象是否兼容。
在进行序列化时会将当前类的serialVersionUID写入到字节序列中,在反序列化时会将当前字节流中的serialVersionUID同本地对象中的serialVersionUID进行对比,如果相同则继续序列化,如果不同则失败报错。
serialVersionUID常量值默认为1L
得分点
兼容性、自定义
参考答案
标准回答
serialVersionUID是序列化版本,为一个类定义序列化版本,是出于兼容性的考虑。如果某个类随着项目进行了升级,那么对于升级之前序列化的数据,在升级之后反序列化时就很可能出现不兼容的情况。如果事先定义了序列化的版本,则在反序列化的时候,只要版本不变就可以将其认定为同一个class文件。Java采用以下的形式来定义序列化版本:
需要注意的是,如果没有显示定义serialVersionUID,则JVM会根据类的信息自动计算出它的值,如果升级前后类的内容发生了变化,该值的计算结果通常就不同,这会导致反序列化的失败。所以,最好在打算序列化的类中显示地定义serialVersionUID,这样即便在序列化后它对应的类被修改了,由于版本号是一致的,所以该对象依然可以被正确的反序列化。
加分回答
如果类的修改会导致反序列化失败,则应该为此类分配新的serialVersionUID,那么对类的哪些内容进行修改会导致反序列化失败呢?
延伸阅读
序列化版本的示例:
/** * 序列化的版本 */ public class IODemo12 { public static void main(String[] args) { testSerialize(); testDeserialize(); } public static void testSerialize() { try ( ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream("C:/work/alpha/dri.txt")); ) { Driver d = new Driver("Tom", 'M', 23); // d.setLicense("H0527"); // d.setLevel(5); oos.writeObject(d); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void testDeserialize() { try ( ObjectInputStream ois = new ObjectInputStream( new FileInputStream("C:/work/alpha/dri.txt")); ) { Driver d = (Driver) ois.readObject(); System.out.println(d); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class Driver implements Serializable { private static final long serialVersionUID = 847704670584248289L; private String name; private char gender; private int age; private String licenseNO; // license -> licenseNO // private int level; private int order; public Driver(String name, char gender, int age) { this.name = name; this.gender = gender; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getLicenseNO() { return licenseNO; } public void setLicenseNO(String licenseNO) { this.licenseNO = licenseNO; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } @Override public String toString() { return "Driver{" + "name='" + name + '\'' + ", gender=" + gender + ", age=" + age + ", licenseNO='" + licenseNO + '\'' + ", order=" + order + '}'; } }