码迷,mamicode.com
首页 > 其他好文 > 详细

序列化的一些注意事项及建议

时间:2014-12-17 12:59:59      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:blog   http   ar   io   os   sp   java   on   数据   

本文来自《改善java的151个建议》


建议11:养成良好习惯,显示声明UID



bubuko.com,布布扣

我们先写一个序列化与反序列化的工具类SerilizationUtils

public class SerializationUtils {

	private static String FILE_NAME="E:/serializable.txt";
	
	public static void writeObject(Serializable s){
		try{
			
			
			ObjectOutputStream oob = new ObjectOutputStream(new FileOutputStream(FILE_NAME));
			oob.writeObject(s);
			oob.close();
		}catch(Exception e){};
	}
	
	public static Object readObject(){
		Object obj=null;
		try{
			
			ObjectInputStream oob = new ObjectInputStream(new FileInputStream(FILE_NAME));
			obj = oob.readObject();
			
			oob.close();
		}catch(Exception e){};
		
		return obj;
	}
}

Person类

public class Person implements Serializable  {

	/**
	 * 这里先不显示的声明UID
	 */
	//private static final long serialVersionUID = 1L;

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	//
	/*private String sex;

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}*/
	
}

首先定义一个消息的产生者Produce

public class Produce {

	public static void main(String[] args){
		
		Person person = new Person();
		person.setName("石仁闯");
		
		//增加sex后
		//person.setSex("男");
		//序列化 保存到磁盘上

		SerializationUtils.writeObject(person);
		System.out.println(person);
	}
}

这里执行了之后  person就被序列化到了E:/serializable.txt


然后定义一个消费者

public class Consumer {
	
	public static void main(String[] args) throws Exception{
		
		//反序列化
		Person p = (Person)SerializationUtils.readObject();
		System.out.println("反序列化得到的值"+p.getName());
		//System.out.println("反序列化得到的值"+p.getSex());
	}

}

好 运行到这里是没有什么问题的;但是如果我们序列化与反序列化的时候参照的不是一个Person  会出现什么情况  ;

比如我们在序列化之前person还是只有一个属性name   执行produce (序列化)之后;给person增加一个sex属性(注意不要再运行produce (序列化)了);

增加了属性之后   我们运行consumer(反序列化);会出现一个错误

bubuko.com,布布扣

书上说的是InvalidClassException错误;但是我亲自执行报的是上面的错误;

为什么会这样呢?

原因是序列化与反序列化对应的类(person)版本不一致;JVM不能把数据流转换为实例对象;

那JVM是怎么判断一个类的对应版本呢?

是通过SerivalVersionUID ,也就流标识符,即类的版本定义

private static final long serialVersionUID = 1L;

UID可以隐式声明和显示声明;隐式声明是编译器自动生成  基本上市唯一的;如果改变了类 ; 它是UID也会改变

在反序列化的时候 jvm会比较数据流中的UID与当前类(person)是否一致;如果一致说明类没有改动;不一致说明是改动了,这是一个很好的效验机制;



但是;有特殊情况;例如:我的类改变不大,我希望在反序列化的时候也能把它序列化出来。那怎么办呢?


既然是判断UID是否一致,那我们让他们的UID是一致的就可以了,显示声明UID 可以很好的解决这一问题;

序列化的一些注意事项及建议

标签:blog   http   ar   io   os   sp   java   on   数据   

原文地址:http://blog.csdn.net/u010634066/article/details/41977771

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!