`

主题:Java序列化的作用

    博客分类:
  • J2SE
 
阅读更多

转自:http://www.iteye.com/topic/1111795

 

序列化是什么: 
  序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。 
  序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例 
  序列化的什么特点: 
  如果某个类能够被序列化,其子类也可以被序列化。声明为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序列化:挑战复杂的面试题与详细解析

    java序列化是面试中经常涉及的重要主题之一。对Java序列化的深入了解不仅可以展示你的编程技能,还能体现出你对Java核心概念的掌握。本文精选了20道复杂的Java序列化面试题,并提供了详细的解析,旨在帮助你更好地...

    java维基源码-java-extra-lectures:有关Java额外讲座的源代码-不在Wiki书的一章中

    使用序列化缓存对象 类加载和实例初始化 数据结构-集合和地图 Java枚举- Java 8流和Lambdas- Jar文件- Java I / O(java.io类)- Java可选- Systembolaget产品的JDBC和Servlet示例- Java网络- Java Swing-GUI编程- ...

    Android上的Java对象反序列化-Android开发

    Android Java反序列化漏洞测试仪关于本项目包含旨在测试和创建Andr中Java反序列化漏洞概念验证(PoC)漏洞的工具的Android应用Android Java反序列...背景Java反序列化漏洞是一个长期以来广为研究的主题。 从本质上讲,

    积分java源码-anoa:用于基于通用格式的数据结构的稳健操作和序列化的Java库

    插件,用于访问和序列化带有 , 和 的结构化数据,并以理智和一致的方式。 基本原理 在 AdGear,我们经常处理事件日志。 事件无处不在,在 Kafka 主题、文件、S3 存储桶等中,它们在 Hadoop map-reduce 作业、Storm ...

    你必须知道的261个java语言问题

    书中精选了Java开发人员经常遇到的261个典型问题,涵盖了基本概念、环境配置、基本语法、异常处理、流操作、图形用户界面编程、网络编程、线程、序列化、数据库操作、Java Web程序设计等各方面的主题,并分别给出了...

    21天学通Java 6(第5版) 源代码

    第3周介绍高级主题,包括输入和输出、对象序列化、通过Internet进行通信、使用数据库、XML、Web服务、servlet和JSP等内容。  本书可作为初学者学习Java编程技术的教程,也可供已掌握其他语言的程序员学习Java时参考

    java面试考题

    接口:Connection、Map、List、Set、Comparable(集合比较)、Serializable(序列化)。 包:java.util、java.lang、java.io、java.sql、javax.net、 java.awt、javax.xml 、javax.sevlet。 1.面向对象的特征有哪些? 1...

    Library:学校 Java 项目

    图书馆计划学校 Java 项目我开始git clone 或到下载源...Numero,贷款类别(借款人、图书、日期): Methodes:- getters, setters, toString,图书馆类(会员列表、外借列表、图书列表):该类是可序列化的,并实现了 M

    java 面试题 总结

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    Java思维导图xmind文件+导出图片

    理解通信协议传输过程中的序列化和反序列化机制 基于框架的RPC通信技术 WebService/ApacheCXF RMI/Spring RMI Hession 传统RPC技术在大型分布式架构下面临的问题 分布式架构下的RPC解决方案 Zookeeper ...

    java面试题

    Hibernate持久化:Hibernate根据定义的映射规则将对象持久化保存到数据库,这就实现了对象的持久化。 Spring由那几个模块组成? 答:Spring主要由7个模块组成: 1:Spring核心容器:提供了Spring框架的基本功能 2...

    你必须知道的261个Java语言问题 中文版

    涵盖了基本概念 环境配置 基本语法 异常处理 流操作 图形用户界面编程 网络编程 线程 序列化 数据库操作 java web程序设计等各方面的主题 并分别给出了详细的解答 而且结合代码示例阐明了技术要点  本书结构清晰 ...

    Java数据编程指南

    数据定义 基本数据操作 数据完整性 表达式 连接 合并 子查询 小结 附录B 序列化 简介 序列化 可串行化的接口 小结 附录C Java和分布式应用程序 分布式系统 分布式...

    21天学通Java_6

    第3周介绍高级主题,包括输入和输出、对象序列化、通过Internet进行通信、使用数据库、XML、Web服务、servlet和JSP等内容。  本书可作为初学者学习Java编程技术的教程,也可供已掌握其他语言的程序员学习Java时参考...

    Java2 學習指南

    @serial 为默认的可序列化字段提供文档 @serialData 为writeObject 或者writeExternal 方法编写的数据提供文档 @serialField 为ObjectStreamField组件提供文档 @since 当引入一个特定改变时 声明发布版本 @throws 与...

    21天学通java6(高清第五版)

    《21天学通Java6》是人民邮电出版社出版的编程技术累图书。内容包括3周的课程,通过学习,...第3周介绍高级主题,包括输入和输出、对象序列化、通过Internet进行通信、使用数据库、XML、Web服务、servlet和JSP等内容。

    超级有影响力霸气的Java面试题大全文档

    内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的...

    AppModular:Android模块化,组件化架构案例。路由+Rxjava+MVP+Okhttp+Retrofit+Glide+公共库

    网络框架(Okhttp+Retrofit+Rxjava)图片框架(Glide)数据存储层Sqlite (原生sqlite+ORM框架的封装)SharedPreferences(工具类)Files(工具类)...通信设计模式(MVP+RxJava+RxBus)数据序列化封装Modular模块的封装G

Global site tag (gtag.js) - Google Analytics