Java序列化的做用

序列化是什么: 
  序列化就是将一个对象的状态(各个属性量)保存起来,而后在适当的时候再得到。 
  序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不只要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例 
  序列化的什么特色: 
  若是某个类可以被序列化,其子类也能够被序列化。声明为static和transient类型的成员数据不能被序列化。由于static表明类的状态, transient表明对象的临时数据。 
  何时使用序列化: 
  一:对象序列化能够实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时同样。 
  二:java对象序列化不只保留一个对象的数据,并且递归保存对象引用的每一个对象的数据。能够将整个对象层次写入字节流中,能够保存在文件中或在网络链接上传递。利用对象序列化能够进行对象的"深复制",即复制对象自己及引用的对象自己。序列化一个对象可能获得整个对象序列。 
  ====================== 
  能够看看接口java.io.serializable的中文解释: 
  Serializable 
  public interface Serializable 
  类经过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将没法使其任何状态序列化或反序列化。可序列化类的全部子类型自己都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。 
  要容许不可序列化类的子类型序列化,能够假定该子类型负责保存和还原超类型的公用 (public)、受保护的 (protected) 和(若是可访问)包 (package) 字段的状态。仅在子类型扩展的类有一个可访问的无参数构造方法来初始化该类的状态时,才能够假定子类型有此责任。若是不是这种状况,则声明一个类为可序列化类是错误的。该错误将在运行时检测到。 
  在反序列化过程当中,将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。可序列化的子类必须可以访问无参数的构造方法。可序列化子类的字段将从该流中还原。 
  当遍历一个图形时,可能会遇到不支持可序列化接口的对象。在此状况下,将抛出 NotSerializableException,并将标识不可序列化对象的类。 
  在序列化和反序列化过程当中须要特殊处理的类必须使用下列准确签名来实现特殊方法: 
  private void writeObject(java.io.ObjectOutputStream out) 
  throws IOException 
  private void readObject(java.io.ObjectInputStream in) 
  throws IOException, ClassNotFoundException; 
  writeObject 方法负责写入特定类的对象的状态,以便相应的 readObject 方法能够还原它。经过调用 out.defaultWriteObject 能够调用保存 Object 的字段的默认机制。该方法自己不须要涉及属于其超类或子类的状态。状态是经过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。 
  readObject 方法负责从流中读取并还原类字段。它能够调用 in.defaultReadObject 来调用默认机制,以还原对象的非静态和非瞬态字段。defaultReadObject 方法使用流中的信息来分配流中经过当前对象中相应命名字段保存的对象的字段。这用于处理类发展后须要添加新字段的情形。该方法自己不须要涉及属于其超类或子类的状态。状态是经过使用 writeObject 方法或使用 DataOutput 支持的用于基本数据类型的方法将各个字段写入 ObjectOutputStream 来保存的。 
  将对象写入流时须要指定要使用的替代对象的可序列化类,应使用准确的签名来实现此特殊方法: 
  ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; 
  此 writeReplace 方法将由序列化调用,前提是若是此方法存在,并且它能够经过被序列化对象的类中定义的一个方法访问。所以,该方法能够拥有私有 (private)、受保护的 (protected) 和包私有 (package-private) 访问。子类对此方法的访问遵循 java 访问规则。 
  在从流中读取类的一个实例时须要指定替代的类应使用的准确签名来实现此特殊方法。 
  ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException; 
  此 readResolve 方法遵循与 writeReplace 相同的调用规则和访问规则。 
  序列化运行时使用一个称为 serialVersionUID 的版本号与每一个可序列化类相关联,该序列号在反序列化过程当中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。若是接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不一样,则反序列化将会致使 InvalidClassException。可序列化类能够经过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其本身的 serialVersionUID: 
  ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 
  若是可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 全部可序列化类都显式声明 serialVersionUID 值,缘由计算默认的 serialVersionUID 对类的详细信息具备较高的敏感性,根据编译器实现的不一样可能千差万别,这样在反序列化过程当中可能会致使意外的 InvalidClassException。所以,为保证 serialVersionUID 值跨不一样 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修改器显示声明 serialVersionUID(若是可能),缘由是这种声明仅应用于当即声明类 -- serialVersionUID 字段做为继承成员没有用处。 
  java.io.Serializable引起的问题——什么是序列化?在什么状况下将类序列化? 
  序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。序列化的实现:将须要被序列化的类实现Serializable接口,该接口没有须要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,而后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就能够将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。 
  序列化:序列化是将对象转换为容易传输的格式的过程。例如,能够序列化一个对象,而后使用 HTTP 经过 Internet 在客户端和服务器之间传输该对象。在另外一端,反序列化将从该流从新构造对象。 
  是对象永久化的一种机制。 
  确切的说应该是对象的序列化,通常程序在运行时,产生对象,这些对象随着程序的中止运行而消失,但若是咱们想把某些对象(由于是对象,因此有各自不一样的特性)保存下来,在程序终止运行后,这些对象仍然存在,能够在程序再次运行时读取这些对象的值,或者在其余程序中利用这些保存下来的对象。这种状况下就要用到对象的序列化。 
  只有序列化的对象才能够存储在存储设备上。为了对象的序列化而须要继承的接口也只是一个象征性的接口而已,也就是说继承这个接口说明这个对象能够被序列化了,没有其余的目的。之因此须要对象序列化,是由于有时候对象须要在网络上传输,传输的时候须要这种序列化处理,从服务器硬盘上把序列化的对象取出,而后经过网络传到客户端,再由客户端把序列化的对象读入内存,执行相应的处理。 
  对象序列化是java的一个特征,经过该特征能够将对象写做一组字节码,当在其余位置读到这些字节码时,能够依此建立一个新的对象,并且新对象的状态与原对象彻底相同。为了实现对象序列化,要求必须可以访问类的私有变量,从而保证对象状态可以正确的得以保存和恢复。相应的,对象序列化API可以在对象重建时,将这些值还原给私有的数据成员。这是对java语言访问权限的挑战。一般用在服务器客户端的对象交换上面,另外就是在本机的存储。 
  对象序列化的最主要的用处就是在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。譬如经过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口 。 
  * 
  Quote: 
  比较java.io.Externalizable和java.io.Serializable 
  http://www.zdnet.com.cn/developer/code/story/0,3800066897,39304080,00.htm 
  即便你没有用过对象序列化(serialization),你可能也知道它。但你是否知道 Java 还支持另一种形式的对象持久化,外部化(externalization)? 
  下面是序列化和外部化在代码级的关联方式: 
  public interface Serializable {} 
  public interface Externalizable extends Serializable { 
  void readExternal(ObjectInput in); 
  void writeExternal(ObjectOutput out); 
  } 
  序列化和外部化的主要区别 
  外部化和序列化是实现同一目标的两种不一样方法。下面让咱们分析一下序列化和外部化之间的主要区别。 
  经过Serializable接口对对象序列化的支持是内建于核心 API 的,可是java.io.Externalizable的全部实现者必须提供读取和写出的实现。Java 已经具备了对序列化的内建支持,也就是说只要制做本身的类java.io.Serializable,Java 就会试图存储和重组你的对象。若是使用外部化,你就能够选择彻底由本身完成读取和写出的工做,Java 对外部化所提供的惟一支持是接口: 
  voidreadExternal(ObjectInput in) 
  void writeExternal(ObjectOutput out) 
  如今如何实现readExternal() 和writeExternal() 就彻底看你本身了。 
  序列化会自动存储必要的信息,用以反序列化被存储的实例,而外部化则只保存被存储的类的标识。当你经过java.io.Serializable接口序列化一个对象时,有关类的信息,好比它的属性和这些属性的类型,都与实例数据一块儿被存储起来。在选择走Externalizable这条路时,Java 只存储有关每一个被存储类型的很是少的信息。 
  每一个接口的优势和缺点 
  Serializable接口 
  · 优势:内建支持 
  · 优势:易于实现 
  · 缺点:占用空间过大 
  · 缺点:因为额外的开销致使速度变比较慢 
  Externalizable接口 
  · 优势:开销较少(程序员决定存储什么) 
  · 优势:可能的速度提高 
  · 缺点:虚拟机不提供任何帮助,也就是说全部的工做都落到了开发人员的肩上。 
  在二者之间如何选择要根据应用程序的需求来定。Serializable一般是最简单的解决方案,可是它可能会致使出现不可接受的性能问题或空间问题;在出现这些问题的状况下,Externalizable多是一条可行之路。 
  要记住一点,若是一个类是可外部化的(Externalizable),那么Externalizable方法将被用于序列化类的实例,即便这个类型提供了Serializable方法: 
  private void writeObject() 
  private void readObject()
java

相关文章
相关标签/搜索