• public interface Serializable
    类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。 可序列化类的所有子类型都是可序列化的。 序列化接口没有方法或字段,仅用于标识可串行化的语义。

    为了允许序列化不可序列化的子类型,子类型可能承担保存和恢复超类型的公共,受保护和(如果可访问)包字段的状态的责任。 子类型可以承担此责任,只有当它扩展的类具有可访问的无参数构造函数来初始化类的状态。 如果不是这样,声明一个类Serializable是一个错误。 错误将在运行时检测到。

    在反序列化期间,非可序列化类的字段将使用该类的public或protected no-arg构造函数进行初始化。 对于可序列化的子类,必须可以访问no-arg构造函数。 可序列化子类的字段将从流中恢复。

    当遍历图形时,可能会遇到不支持Serializable接口的对象。 在这种情况下,将抛出NotSerializableException,并将标识不可序列化对象的类。

    在序列化和反序列化过程中需要特殊处理的类必须采用具有这些精确签名的特殊方法:

      private void writeObject(java.io.ObjectOutputStream out)
         throws IOException
     private void readObject(java.io.ObjectInputStream in)
         throws IOException, ClassNotFoundException;
     private void readObjectNoData()
         throws ObjectStreamException; 

    writeObject方法负责为其特定的类编写对象的状态,以便相应的readObject方法可以恢复它。 可以通过调用out.defaultWriteObject来调用保存对象字段的默认机制。 该方法不需要关注属于其超类或子类的状态。 通过使用writeObject方法或通过使用DataOutput支持的原始数据类型的方法将各个字段写入ObjectOutputStream来保存状态。

    readObject方法负责从流中读取并恢复类字段。 它可以调用in.defaultReadObject来调用恢复对象的非静态和非瞬态字段的默认机制。 defaultReadObject方法使用流中的信息将保存在流中的对象的字段分配给当前对象中相应命名的字段。 当处理类进化到添加新字段时,这将处理这种情况。 该方法不需要关注属于其超类或子类的状态。 通过使用writeObject方法或通过使用DataOutput支持的原始数据类型的方法将各个字段写入ObjectOutputStream来保存状态。

    如果序列化流未将给定类列为反序列化对象的超类,则readObjectNoData方法负责初始化其特定类的对象的状态。 这可能发生在接收方使用与发送方不同的反序列化实例的类的版本的情况下,并且接收者的版本扩展了不被发送者版本扩展的类。 如果序列化流已被篡改,也可能发生这种情况; 因此,尽管存在“敌对”或不完整的源流,readObjectNoData可用于正确初始化反序列化对象。

    在将对象写入到流中时需要指定要使用的替代对象的可序列化类应实现具有确切签名的特殊方法:

      ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; 

    如果该方法存在并且可以通过在被序列化的对象的类中定义的方法来访问,则该writeReplace方法通过序列化来调用。 因此,该方法可以具有私有,受保护和包私有访问。 子类访问此方法遵循java可访问性规则。

    当从流中读取实例时需要指定替换的类应实现具有确切签名的特殊方法。

      ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException; 

    这个readResolve方法遵循与writeReplace相同的调用规则和可访问性规则。

    序列化运行时将每个可序列化的类与称为serialVersionUID的版本号相关联,该序列号在反序列化期间用于验证序列化对象的发送者和接收者是否已加载与该序列化兼容的对象的类。 如果接收方加载了一个具有不同于相应发件人类的serialVersionUID的对象的类,则反序列化将导致InvalidClassException 。 一个可序列化的类可以通过声明一个名为"serialVersionUID"的字段来显式地声明它自己的serialVersionUID,该字段必须是静态的,最终的,类型是long

      ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 

    如果可序列化类没有显式声明serialVersionUID,则序列化运行时将根据Java(TM)对象序列化规范中所述的类的各个方面计算该类的默认serialVersionUID值。 但是, 强烈建议所有可序列化的类都明确声明serialVersionUID值,因为默认的serialVersionUID计算对类详细信息非常敏感,这可能会因编译器实现而异,因此可能会在反InvalidClassException化期间导致InvalidClassException的InvalidClassException。 因此,为了保证不同Java编译器实现之间的一致的serialVersionUID值,一个可序列化的类必须声明一个显式的serialVersionUID值。 还强烈建议,显式的serialVersionUID声明在可能的情况下使用private修饰符,因为这种声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无效。 数组类不能声明一个显式的serialVersionUID,所以它们总是具有默认的计算值,但是对于数组类,放弃了匹配serialVersionUID值的要求。

最新文章

  1. OpenCV图像的全局阈值二值化函数(OTSU)
  2. DOM加载顺序
  3. 重构第18天 用条件语句来代替异常(Replace exception with conditional)
  4. linux进程间通信-有名管道(FIFO)
  5. Fresco 源码分析(三) Fresco服务端处理(3) DataSource到Producer的适配器逻辑以及BitmapMemoryCacheProducer处理的逻辑
  6. python 递归
  7. Erlang安装笔记
  8. BZOJ 3875: [Ahoi2014]骑士游戏 dp+spfa
  9. [转载][HTML] 普通的DIV分层以及版透明效果
  10. SuperSocket快速入门(一):什么是SuperSocket
  11. Silverlight调用网站项目的Session
  12. MIPI CSI-2规范一——概述及层级
  13. hihoCoder 1252 Kejin Game
  14. react配置之浅谈
  15. Yii2中把路由地址中的%2F改为/
  16. 嵌入式Linux学习路线
  17. ubuntu 安装kafka
  18. JavaScript之子类构建工具
  19. J - Vertical Histogram(1.5.7)
  20. subprocess 粘包问题

热门文章

  1. HDU_2102 A计划 【BFS】
  2. C# 判断两个集合(List)是否相等
  3. Nginx 安装--图片服务器搭建
  4. Python实现图片验证码识别
  5. python小商店
  6. java c c++大学补遗
  7. oracle 操作实例(一)----rman 全备恢复
  8. mongoDB--万能的$关键字
  9. 8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07
  10. VS 连接数据库报错:在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误