Serializable 序列化问题学习

声明:  关于序列化/反序列化 这有一篇javaeye中很全面的解释: 浏览.  本文主要记录我对平台中的序列化/反序列化的理解学习. 由于个人文采有限, 表达,组织不合适, 及粘贴代码不完整, 望见谅

 

在平台中在自定义异常类中,看到有 private static final long serialVersionUID = -7564015249480613950L;

这行代码, 有几个疑问:

1. 这行代码作用是什么? 不加有怎样?

网上搜了一下大体知道,这是个序列化和返序列化版本版本控制的标志.对于所用实现java.lang.Serializable接口的类都建议使用.(关于序列化和反序列化见 3 )

测试1: 不添加序列化

 

	//private static final long serialVersionUID = 5159342088681301L;

 使用jdk1.5 编译,序列化产生对象文件.

使用jdk1.6 反序列获得对象,可以获得对象的属性.

?问题1  并没有报错,说版本不同? =>已解决

:是我对此理解还有问题? 

http://www.blogjava.net/invisibletank/archive/2007/11/15/160684.html

中看到原来版本控制是说,当

"如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。 "

测试2: 

先序列化一个对象, 然后在类中增加一个成员变量 short shortVar = 0;

然后调用反序列化方法, 结果:

 

java.io.InvalidClassException: com.bryant.test.SerialTest; local class incompatible: stream classdesc serialVersionUID = 659456840250255615, local class serialVersionUID = -7474528909570989615
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:546)

 符合预测,即没有写serialVersionUID时,版本不同报错.

测试3 : 添加版本控制,

先序列化对象, 然后删除一个成员变量 short shortVar = 0; 进行反序列化,

运行正常.

至此问题1解决.

总结: 在一个可以序列化类中,加入serialVersionUID可以保持版本兼容:(避免 当序列化一个对象后,然后增减类成员变量,再进行反序列化时 程序出异常)

 

2. 这个代码变量的值是怎么获得的? 

在eclipse中当类实现Serrial接口时,eclipse会在类所在行叹号提示,

 

"The serializable class SerialTest does not declare a static final serialVersionUID field of type 

 long ", ctrl + 1 : 点击"add default serial version Id" ,自动生成 

 

	private static final long serialVersionUID = 1L;

 点击"add generated serial version Id " ,生成

 

 

private static final long serialVersionUID = 8515159342088681301L;

解决.

 

 问题2 ,default和 generated Id 区别?

 

3. 序列化/反序列化

序列化: 把java对象生成一个文件(这些文件包含对象的所有信息)

反序列化: 把序列化生成的文件 转化成java对象

 

怎么序列化/反序列化一个对象?

3.1 序列化步骤

创建文件对象(所有序列化对象生成的文件) ->封装成Inputstream流 -> 封装成ObjectOutputStream对象oos

通过调用oos的writeObject()方法,输出序列化对象.

 

 

	public static void serialObj(Object obj) throws IOException{
		File file = new File("c:\\", obj.toString() );
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(file));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}	//create output stream
		
		try {
			oos.writeObject(obj);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("servial error!");
			e.printStackTrace();
		}finally{
			oos.close();	
		}
		logger.info("servial ok!");
		
	}

 3.2 反序列化步骤

创建文件对象 --> 封装成inputstream流 --> 封装成ObjectinputStream流对象ois

调用ois的readObject() 方法返回对象,

强制类型转换成已知类型的对象.

 

 

	public void getSerivalObj() throws FileNotFoundException, IOException, ClassNotFoundException{
		PropertyConfigurator.configure("D:/workspace/common_jars/log4j.properties");
		File file = new File("c:\\", String.valueOf( "com.bryant.test.SerialTest@1270b73" ) );
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
		Object obj = ois.readObject();
		logger.info( ((SerialTest)obj).intTest + ((SerialTest)obj).s );
		
		
	}	

你可能感兴趣的:(eclipse,C++,c,log4j,C#)