java序列化的作用


  最近在阅读corej2eepatterns的时候发现例子里用于在各个层次里进行传输的to(datatransferobject)都完成了java. io. serializable接口, 看到这些偶突然感到茅塞顿开~困扰了很久的关于serializable的疑问渐渐解开了, 查找相关资料并总结如下:

  序列化是什么:

  序列化就是将一个对象的形态(各个属性量)保存起来, 然后在适当的时候再取得。

  序列化分为两大局部:序列化和反序列化。 序列化是这个过程的第一局部, 将数据分解成字节流, 以便

  存储在文件中或在网络上传输。 反序列化就是打开字节流并重构对象。 对象序列化不只要将基本数据类型转换成字节表示, 有时还要恢复数据。 恢复数据要求有恢复数据的对象实例

  序列化的什么特点:

  如果某个类能够被序列化, 其子类也可以被序列化。 声明为static和transient类型的成员数据不能被序列化。 由于static代表类的形态, transient代表对象的临时数据。

  什么时候使用序列化:

  一:对象序列化可以完成散布式对象。 主要应用例如:rmi要应用对象序列化运行近程主机上的服务, 就像在本地机上运行对象时一样。

  二:java对象序列化不只保留一个对象的数据, 而且递归保存对象援用的每个对象的数据。 可以将整个对象层次写入字节流中, 可以保存在文件中或在网络衔接上传递。 应用对象序列化可以进行对象的"深复制", 即复制对象自身及援用的对象自身。 序列化一个对象能够失掉整个对象序列。

  类经过完成java. io. serializable接口以启用其序列化功能。 未完成此接口的类将无法使其任何形态序列化或反序列化。 可序列化类的一切子类型自身都是可序列化的。 序列化接口没有方法或字段, 仅用于标识可序列化的语义。

  要允许不可序列化类的子类型序列化, 可以假定该子类型负责保存和还原超类型的公用(public)、受保护的(protected)和(如果可访问)包(package)字段的形态。 仅在子类型扩展的类有一个可访问的无参数构造方法来初始化该类的形态时, 才可以假定子类型有此责任。 如果不是这种情况, 则声明一个类为可序列化类是错误的。 该错误将在运行时检测到。

  在反序列化过程中, 将使用该类的公用或受保护的无参数构造方法初始化不可序列化类的字段。 可序列化的子类必须能够访问无参数的构造方法。 可序列化子类的字段将从该流中还原。

  当遍历一个图形时, 能够会遇到不支持可序列化接口的对象。 在此情况下, 将抛出notserializableexception, 并将标识不可序列化对象的类。

  在序列化和反序列化过程中需求特殊处理的类必须使用下列精确签名来完成特殊方法:

  writeobject方法负责写入特定类的对象的形态, 以便相应的readobject方法可以还原它。 经过调用out. defaultwriteobject可以调用保存object的字段的默许机制。 该方法自身不需求涉及属于其超类或子类的形态。 形态是经过使用writeobject方法或使用dataoutput支持的用于基本数据类型的方法将各个字段写入objectoutputstream来保存的。

  readobject方法负责从流中读取并还原类字段。 它可以调用in. defaultreadobject来调用默许机制, 以还原对象的非静态和非瞬态字段。 defaultreadobject方法使用流中的信息来分配流中经过以后对象中相应命名字段保存的对象的字段。 这用于处理类开展后需求添加新字段的情形。 该方法自身不需求涉及属于其超类或子类的形态。 形态是经过使用writeobject方法或使用dataoutput支持的用于基本数据类型的方法将各个字段写入objectoutputstream来保存的。

  将对象写入流时需求指定要使用的替代对象的可序列化类, 应使用精确的签名来完成此特殊方法:

  此writereplace方法将由序列化调用, 前提是如果此方法存在, 而且它可以经过被序列化对象的类中定义的一个方法访问。 因而, 该方法可以拥有公有(private)、受保护的(protected)和包公有(package-private)访问。 子类对此方法的访问遵循java访问规则。

  在从流中读取类的一个实例时需求指定替代的类应使用的精确签名来完成此特殊方法。

  序列化运行时使用一个称为serialversionuid的版本号与每个可序列化类相关联, 该序列号在反序列化过程中用于验证序列化对象的发送者和接纳者是否为该对象加载了与序列化兼容的类。 如果接纳者加载的该对象的类的serialversionuid与对应的发送者的类的版本号不同, 则反序列化将会招致invalidclassexception。 可序列化类可以经过声明名为"serialversionuid"的字段(该字段必须是静态(static)、最终(final)的long型字段)显式声明其本人的serialversionuid:

  如果可序列化类未显式声明serialversionuid, 则序列化运行时将基于该类的各个方面计算该类的默许serialversionuid值, 如“

  java(tm)对象序列化规范”中所述。 不过, 激烈建议一切可序列化类都显式声明serialversionuid值, 缘由计算默许的serialversionuid对类的详细信息具有较高的敏理性, 依据编译器完成的不同能够千差万别, 这样在反序列化过程中能够会招致意外的invalidclassexception。 因而, 为保证serialversionuid值跨不同java编译器完成的一致性, 序列化类必须声明一个明白的serialversionuid值。 还激烈建议使用private修改器显示声明serialversionuid(如果能够), 缘由是这种声明仅应用于立刻声明类--serialversionuid字段作为承继成员没有用处。

  java. io. serializable引发的成绩——什么是序列化?在什么情况下将类序列化?

  序列化就是一种用来处理对象流的机制, 所谓对象流也就是将对象的内容进行流化。 可以对流化后的对象进行读写操作,faceshop护肤品官方旗舰店 也可将流化后的对象传输于网络之间。 序列化是为了处理在对对象流进行读写操作时所引发的成绩。 序列化的完成:将需求被序列化的类完成serializable接口, 该接口没有需求完成的方法, implementsserializable只是为了标注该对象是可被序列化的, 然后使用一个输入流(如:fileoutputstream)来构造一个objectoutputstream(对象流)对象, 接着, 使用objectoutputstream对象的writeobject(objectobj)方法就可以将参数为obj的对象写出(即保存其形态), 要恢复的话则用输入流。

  序列化:序列化是将对象转换为容易传输的格式的过程。 例如, 可以序列化一个对象, 然后使用http经过internet在客户端和

  服务器之间传输该对象。 在另一端, 反序列化将从该流重新构造对象。

  是对象永世化的一种机制。

  确切的说应该是对象的序列化, 普通顺序在运行时, 产生对象, 这些对象随着顺序的中止运行而消逝, 但如果我们想把某些对象(由于是对象, 所以有各自不同的特性)保存下来, 在顺序终止运行后, 这些对象依然存在, 可以在顺序再次运行时读取这些对象的值, 或者在其他顺序中应用这些保存下来的对象。 这种情况下就要用到对象的序列化。

  只要序列化的对象才可以

  服务器硬盘上把序列化的对象取出, 然后经过网络传到客户端, 再由客户端把序列化的对象读入内存, 执行相应的处理。

  对象序列化是java的一个特征, 经过该特征可以将对象写作一组字节码, 当在其他位置读到这些字节码时, 可以依此创立一个新的对象, 而且新对象的形态与原对象完全相同。 为了完成对象序列化, 要求必须能够访问类的公有变量, 从而保证对象形态能够正确的得以保存和恢复。 相应的, 对象序列化api能够在对象重建时, 将这些值还原给公有的数据成员。 这是对java语言访问权限的挑战。 通常用在服务器客户端的对象

  交换下面, 另外就是在本机的存储。

  对象序列化的最主要的用处就是在传递, 和保存对象(object)的时候, 保证对象的完好性和可传递性。 譬如经过网络传输, 或者把一个对象保存成一个文件的时候, 要完成序列化接口。

  即便你没有用过对象序列化(serialization), 你能够也晓得它。 但你是否晓得

  java还支持另外一种方式的对象持久化, 外部化(externalization)?

  下面是序列化和外部化在代码级的关联方式:

  序列化和外部化的主要区别

  外部化和序列化是完成同一目标的两种不同方法。 下面让我们分析一下序列化和外部化之间的主要区别。

  经过serializable接口对对象序列化的支持是内建于核心api的, 但是java. io. externalizable的一切完成者必须提供读取和写出的完成。 java曾经具有了对序列化的内建支持, 也就是说只需制作本人的类java. io. serializable, java就会试图存储和重组你的对象。 如果使用外部化, 你就可以选择完全由本人完成读取和写出的工作, java对外部化所提供的唯一支持是接口:

  序列化会自动存储必要的信息, 用以反序列化被存储的实例, 而外部化则只保存被存储的类的标识。 当你经过java. io. serializable接口序列化一个对象时, 有关类的信息, 比如它的属性和这些属性的类型, 都与实例数据一起被存储起来。 在选择走externalizable这条路时, java只存储有关每个被存储类型的非常少的信息。

  每个接口的优点和缺点

  JAVA·优点:内建支持

  ·优点:易于完成

  ·缺点:占用空间过大

  ·缺点:由于额外的开销招致速度变比拟慢

  ·优点:开销较少(顺序员决定存储什么)

  ·优点:能够的速度提升

  ·缺点:虚拟机不提供任何帮助, 也就是说一切的工作都落到了开发人员的肩上。

  在两者之间如何选择要依据应用顺序的需求来定。 serializable通常是最简单的处理方案, 但是它能够会招致出现不可接受的性能成绩或空间成绩;在出现这些成绩的情况下, externalizable能够是一条可行之路。

  要记住一点, 如果一个类是可外部化的(externalizable), 那么externalizable方法将被用于序列化类的实例, 即便这个类型提供了serializable方法:

posted on 2011-05-19 20:03  jiyizhen3721  阅读(442)  评论(0编辑  收藏  举报