`

主题: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编程语言中,对象的序列化和反序列化是两个关键的概念,它们对于数据存储、网络传输以及持久化有着重要的作用。这篇文章将深入探讨这两个主题,并通过实践例子来阐述其工作原理。 **序列化(Serialization)*...

    如何正确的使用Java序列化技术

    ### 如何正确使用Java序列化技术 #### 技术研究系列 ...本文详细介绍了Java序列化技术的基础知识、序列化与反序列化的具体操作,以及高级主题的探索。希望这些内容能够帮助开发者更好地理解和应用Java序列化技术。

    第38天:WEB漏洞-反序列化之PHP&JAVA全解(下)1

    0x02部分,通过登录接口的响应数据,可以看到返回的JWT(JSON Web Token)中可能包含了Java序列化数据。这段数据以“rO0AB”开头,表明它可能是Java的序列化数据。通过Python脚本解码并利用SerializationDumper工具...

    Java序列化与反序列化<转>

    Java序列化与反序列化是Java编程中一个重要的概念,它允许我们将对象的状态转换为字节流,以便存储或在网络中传输。这个过程被称为序列化,而将字节流恢复为对象的过程则称为反序列化。Java提供了一个内置的机制来...

    利用java序列化实现基于文件的快速索引

    在“利用java序列化实现基于文件的快速索引”这一主题中,我们将探讨如何利用Java的序列化机制来创建高效的数据索引,从而加速文件数据的检索。 首先,了解Java序列化的基本概念。在Java中,一个类如果实现了`java....

    序列化和反序列化dll文件和proto

    用户可以编写.proto文件,定义消息类型,然后编译成各种目标语言(如C++、Java或Python)的类,这些类可以用于序列化和反序列化数据。 在处理Proto文件时,序列化意味着将根据.proto文件定义的消息实例转换为二进制...

    序列化和反序列化doc文档.rar

    在这个主题中,我们将深入探讨序列化和反序列化的概念,它们的工作原理,以及在实际应用中的选择策略。 首先,我们需要理解什么是序列化。序列化是指将对象的状态转换为可存储或可传输的形式,通常是一个二进制流或...

    Protocol buffers 反序列化 一键protoc反序列化

    在本主题中,我们将深入探讨Protocol Buffers的反序列化过程,以及如何利用工具如`tool.exe`来实现16进制数据的一键反序列化。 1. **什么是反序列化**: 反序列化是将之前通过序列化过程转换为字节流的数据恢复成...

    序列化(三) 实例分析深入了解序列化

    这篇博客“序列化(三) 实例分析深入了解序列化”深入探讨了这一主题,我们将基于这个话题展开详细的讨论。 1. **序列化的定义与作用**: 序列化是将一个对象转换为可传输或存储的形式的过程。在Java中,它通过实现...

    S25-hessian反序列化1

    【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...

    消息序列化/反序列化的基准和用法

    1. **对象转换**:将内存中的对象转换成字节流,这个过程可以使用各种序列化库来实现,如Java的`java.io.Serializable`接口,Python的pickle模块,或者JSON格式。 2. **编码**:在序列化过程中,数据可能需要被编码...

    memcached各种序列化策略之session共享

    - **Java序列化**:Java自带的标准序列化机制,简单易用,但相对较慢且序列化后的数据较大。 4. **Memcached与Tomcat整合**:文件名中提到了Apache Tomcat,这是一款流行的Java Servlet容器。在Tomcat中配置...

    vc++实现反射式数据库模版(3.序列化、反序列化与消息映射)

    本文将深入探讨如何在C++中实现反射,并专注于序列化、反序列化以及消息映射这三大主题。 **序列化**是将对象的状态转换为可以存储或传输的数据格式的过程,通常是XML、JSON或二进制。在MFC中,通过`CObject`类的...

    序列化工具(Gson, Jackson, FastJson, ProtoBuf)

    在这个主题中,我们将深入探讨四种常用的序列化工具:Gson, Jackson, FastJson和ProtoBuf,以及与ProtoBuf相关的`proto.exe`工具。 1. Gson(Google Gson): Gson是由Google提供的Java库,用于将Java对象转换为...

    动态调用webservice与复杂对象的序列化

    在Web服务上下文中,序列化特别重要,因为它允许我们将Java对象或.NET对象转换为可以在网络上传输的格式。对于复杂的对象结构,如嵌套对象或包含自定义类型,序列化器需要正确处理这些关系。在Java中,可以使用Java...

    tomcat-7.0.47-memcached-各种序列化策略-session共享

    Tomcat提供了多种序列化策略,包括默认的Java序列化(Serializable)、JSON序列化(如Jackson或Gson)、或者自定义的序列化方式。每种策略都有其优缺点: 1. **Java序列化**:默认的序列化方式,简单易用,但序列化...

    JAVA【第3章:Java基础程序设计】_Java数据类型

    在Java编程语言中,数据类型是程序设计的基础,它们决定了变量可以存储的值的种类和...理解并熟练运用这些知识是编写有效Java代码的基础,对于后续的面向对象编程、异常处理、输入输出、集合框架等进阶主题都至关重要。

    Java核心技术卷2.zip

    5. **序列化**:Java序列化允许将对象转换为字节流,以便存储或在网络上传输。`Serializable`接口、`ObjectOutputStream`和`ObjectInputStream`是实现序列化和反序列化的关键组件。 6. **安全**:Java的安全模型...

    java反序列化漏洞-验证.rar

    标签“java反序列化漏洞 java反序列化 java反序列化漏洞-验证方法”进一步强调了本主题的焦点。这些标签表明该资源涵盖了从基础概念到具体验证方法的全面讨论,包括: 1. **Java反序列化漏洞**:当不信任的数据源...

    Hessian 的字段序列化小记

    本文将围绕"Hessian的字段序列化小记"这一主题,深入探讨Hessian的工作原理、序列化过程以及其在实际应用中的价值。 Hessian的目标是通过减少数据传输的体积来提高网络通信的效率。相比于XML和JSON等文本格式,...

Global site tag (gtag.js) - Google Analytics