关于java序列化的一些问题
1、序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保 存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
2.什么是反序列化
和上面相反,就是把object states转换为各种对象状态
3、什么情况下需要序列化
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候。(大家可以看看String类,肯定是会implements java.io.Serializable)
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候、
3、相关注意事项
a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口
b)序列化时,只对对象的状态进行保存,而不管对象的方法
c)对于关键词transient,表示一个域不会被序列化。举例说明
public class Ca implements Serializable {
private static final long serialVersionUID = 2161216686162584206L;
int a;
transient String b;
Ca(int a,String b){
this.a=a;
this.b=b;
}
public String toString(){
return "a = "+a+",b = "+b;
}
}
在另外类中调用toString方法。
Ca a = new Ca(1,"test");
System.out.println(a);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:\\test.out"));
oos.writeObject(a);
oos.reset();
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:\\test.out"));
a = (Ca)ois.readObject();
System.out.println(a);
如果 transient String b;这样出来的效果是
a = 1,b = test
a = 1,b = null
去掉的话
a = 1,b = test
a = 1,b = test
这样就可以知道transient在反序列化的时候不能得到值,因为写入的时候就没有被序列化
d) serialVersionUID 用来表明类的不同版本间的兼容性。如果你修改了此类, 要修改此值。否则以前用老版本的类序列化的类恢复时会出错.
在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID,对于Test.class,执行命令:serialver Test。
在项目中建议大家不要改 serialVersionUID 这个值。,特别是要用的缓存。一旦serialVersionUID被改变,旧有的序列化对象就不能被被反序列化了,会抛出如下异常:
java.io.InvalidClassException: MyObject; local class incompatible: stream classdesc serialVersionUID = a, local class serialVersionUID = b