注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

老陈的博客

非淡泊无以明志,非宁静无以致远,说的是心态!

 
 
 

日志

 
 

Java对象的序列化和反序列化[转]  

2009-12-29 22:52:17|  分类: 学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1.定义:

序列化--将对象写到一个输出流中。反序列化则是从一个输入流中读取一个对象。类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才能被序列化和反序列化。这个接口是一个表示型的接口。serialVersionUID是一个串行化类的通用标示符,反串行化就是使用这个标示符确保一个加载的类对应一个可串行化的对象。

自 己指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原,还原后的对象照样可以使用,而且还多 了方法可以用。serialVersionUID的生成,可以写1,也可以写2,但最好还是按照摘要算法,生成一个惟一的指纹数字,eclipse可以自 动生成的,jdk也自带了这个工具。一般写法类似于
private static final long serialVersionUID = -763618247875550322L;

 2.序列化步骤:

1)创建一个对象输出流:可以包装一个其他类型的输出流。

2)通过对象输出流的writeObject()写对象。注意使用类型转化,转换为相应的类的对象。

3.反序列化步骤:

1)创建一个对象输入流:可以包装一个其他类型的输出流。

2)通过对象输出流的readObject()写对象。

4.什么对象需要被序列化?

序列化的基本想法是完成对实例信息的保证。因为实例信息在运行结束后就消失了。要储存什么信息呢?一定不是关于方法的信息。

5.使用注意事项:

a. 有些属性处于安全考虑不能被序列化(或者不能被序列化),则用transit修饰,若想进一步控制序列化和反序列化,则类中提供readObject() 方法和writeObject()方法,(反)序列化时就会调用自定义的方法。注意这两个方法不是在java.io.Serializable接口定义 的,而是在ObjectInputStream和ObjectOutputStream类中定义的,这两个类实现ObjectInput 和ObjectOutput两个接口。下边是一个可变数组的例子,取自Java in a Nutshell 2rd Edition,它在串行化实现了高效的针对可变数组程度调整的方法:

public class IntList implements Serializable
{
private int[] nums = new int[8]; // An array to store the numbers.
private transient int size = 0; // Index of next unused element of nums[].
/** Return an element of the array */
public int elementAt(int index) throws ArrayIndexOutOfBoundsException {
if (index >= size) throw new ArrayIndexOutOfBoundsException(index);
else return nums[index];
}
/** Add an int to the array, growing the array if necessary. */
public void add(int x) {
if (nums.length == size) resize(nums.length*2); // Grow array, if needed.
nums[size++] = x; // Store the int in it.
}
/** An internal method to change the allocated size of the array. */
protected void resize(int newsize) {
int[] oldnums = nums;
nums = new int[newsize]; // Create a new array.
System.arraycopy(oldnums, 0, nums, 0, size); // Copy array elements.
}
/** Get rid of unused array elements before serializing the array. */
private void writeObject(ObjectOutputStream out) throws IOException {
if (nums.length > size) resize(size); // Compact the array.
out.defaultWriteObject(); // Then write it out normally.
}
/** Compute the transient size field after deserializing the array. */
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject(); // Read the array normally.
size = nums.length; // Restore the transient field.
}
}

b.由于串行化是针对类的实例,也就是对象的,所以static这样的成员是类相关的,也就不会被串行化。
c.注意,API中一个类一旦被串行化了,那么它的父类都是串行化的。你自己设计的类要是想被串行化,那么其父类要确保都串行化。父类一旦串行化,则子类们都自动实现了串行化。所以内部类和可扩展类不建议串行化。

本文出处:http://blog.csdn.net/gnuhpc/archive/2009/10/24/4722525.aspx

  评论这张
 
阅读(52)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017