一、浩言
优雅的人生,是一颗平静的心,平和的心态,平淡的活法,滋养出来的从容和恬淡。
二:问
序列化和反序列化,如果再把类修改比如新增了字段,那么serialVersionUID需要做修改吗?如果不做修改怎么兼容之前已经序列化的数据?
三:测试
这几天开始面试,对于一些面试问题,耗子打算坐下记载,并且花时间去研究下。今天耗子简直受打击了,倒不是说上午面试,上午面试的还好,主要是线程这一块我的确是菜,接下来也会去专门花时间去研究这个东西,但是下午的面试我就太受打击了,都问的我开始怀疑人生了,说多了都是泪呀。好吧,先说说上面的问题。
3.1
序列化和反序列化定义
序列化:将类转换为字节序列的过程称为序列化。
反序列化:把字节序列转换为对象的过程称为反序列化。
序列化作用:
1):将对象转换为字节序列保存到磁盘上。
2):可以在网络上传输字节序列。
觉得这篇<a href="http://www.cnblogs.com/doudouxiaoye/p/5774327.html">博客</a>讲的很不错
下面看看自己测试的代码:
package com.mouse.moon.serializable;
import java.io.Serializable;
public class Student implements Serializable{
/**
* 序列号
*/
private static final long serialVersionUID = 2L;
//private static final long serialVersionUID = 1L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.mouse.moon.serializable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Main {
public static void main(String args[]) throws IOException{
Student student = new Student();
student.setAge(10);
student.setName("123");
//指定序列化的位置
FileOutputStream fileOut = new FileOutputStream("D:/student123.ser");
ObjectOutputStream out =new ObjectOutputStream(fileOut);
out.writeObject(student);
out.close();
fileOut.close();
System.out.println("序列化完毕!!!");
}
}
package com.mouse.moon.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class FMain {
public static void main(String args[]) throws IOException, ClassNotFoundException{
Student stu = new Student();
FileInputStream fileInStr = new FileInputStream("D:/student123.ser");
ObjectInputStream in = new ObjectInputStream(fileInStr);
stu = (Student)in.readObject();
in.close();
fileInStr.close();
System.out.println(stu.getAge());
}
}
如果改了Student中的序列id,然后再反序列的话就会报错如下
Exception in thread "main" java.io.InvalidClassException: com.mouse.moon.serializable.Student; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at com.mouse.moon.serializable.FMain.main(FMain.java:15)
然后在Student中增加类的面试
package com.mouse.moon.serializable;
import java.io.Serializable;
public class Student implements Serializable{
/**
* 序列号id
*/
private static final long serialVersionUID = 2L;
//private static final long serialVersionUID = 1L;
private String name;
private int age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
四:serialVersionUID的作用
serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
显式地定义serialVersionUID有两种用途:
1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
其实这个2中的我不是很明白,如果不通版本对应不同的serialVersionUID,那么对象里面肯定就只有一个,那么其他的在反序列化的时候跟现在的类里面的序列号不一样不就会报错吗?这还怎么兼容了?