JDK8源码阅读(三) java.io.Serializable

导读:本篇文章讲解 JDK8源码阅读(三) java.io.Serializable,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、类

1.1 类修饰符

JDK8源码阅读(三) java.io.Serializable

 

A. 是一个接口;

B. 类的可序列化性由实现java.io.serializable接口的类启用。不实现此接口的类将不具有序列化或反序列化的任何状态。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义;

C. 为了使得不可序列化类的子类型被序列化,子类型可能会负责保存和还原父类型的公共、受保护和(如果可访问)包字段的状态。只有子类型扩展的类具有可访问的无参构造函数才能承担初始化类的状态的责任。如果不是这样,则声明类可序列化是错误的,运行时将检测到错误。

D. 在反序列化过程中,将使用类的public或protected无参构造函数初始化不可序列化类的字段。可以序列化的子类必须可以访问无参数构造函数。可序列化子类的字段将从流中还原。

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

F. 在序列化和反序列化过程中需要特殊处理的类必须实现具有这些确切签名的特殊方法:

   JDK8源码阅读(三) java.io.Serializable

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

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

   f3. 如果序列化流未将给定类作为要反序列化的对象的超类列出,则readObjectNoData方法负责为其特定类初始化对象的状态。在接收方使用反序列化实例类的不同版本而不是发送方的情况下,可能会发生这种情况: 接收方的版本扩展了不由发送方版本扩展的类。如果序列化流已被篡改,也可能发生这种情况;因此,尽管源流“敌对”或不完整,但readObjectNoData对于正确初始化反序列化对象非常有用。 

G. 需要指定在将对象写入流时要使用的可选对象的可序列化类应使用准确的签名实现此特殊方法:

JDK8源码阅读(三) java.io.Serializable

   g1. 如果方法存在,则通过序列化调用此WriteReplace方法,并且可以从被序列化对象的类中定义的方法访问它。因此,该方法可以具有私有、受保护和包私有访问。这种方法的子类访问遵循Java可访问性规则。

H. 当从流中读取替换实例时,需要指定替换的类应使用准确的签名实现此特殊方法:

JDK8源码阅读(三) java.io.Serializable

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

I. 序列化运行时将与每个可序列化类的一个版本号(称为serialversionID)关联,该版本号在反序列化期间用于验证序列化对象的发送方和接收方是否已为该对象加载了与序列化兼容的类。如果接收器为与对应发送方类的serialVersionUID不同的对象加载了一个类,则反序列化将导致InvalidClassException。可序列化类可以通过声明名为“serialVersionUID”的字段显式声明自己的serialVersionUID,该字段必须是静态的、最终的且类型为long,格式如下:

JDK8源码阅读(三) java.io.Serializable

J. 如果序列化类没有显式声明SerialValueUID,则序列化运行时将根据类的各个方面计算该类的默认SerialValueUID值,如Java(TM)对象序列化规范中所描述的。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类详细信息高度敏感,这些详细信息可能因编译器实现而异,因此在反序列化期间可能会导致意外的invalidClassExceptions。因此,为了保证跨Java编译器实现一致的SerialValueUID值,可序列化类必须声明显式SerialValueUID值。还强烈建议显式serialversionuid声明尽可能使用私有修饰符,因为此类声明仅适用于立即声明的类–serialversionuid字段作为继承成员不有用。数组类不能声明显式的serialversionID,因此它们始终具有默认的计算值,但数组类不需要匹配serialversionID值。

 

1.2 类结构图

JDK8源码阅读(三) java.io.Serializable

 

二、字段

1.1 字段列表

无。

 

三、方法

3.1 方法列表

无。

3.2 方法修饰符

无。

3.3 方法详解

3.3.0 [静态]代码块

无。

 

 

四. JDK8源码阅读系列链接

  1. JDK8源码阅读(一) java.util.Object
  2. JDK8源码阅读(二) java.util.Objects
  3. JDK8源码阅读(三) java.io.Serializable   
  4. JDK8源码阅读(四) java.lang.Comparable
  5. JDK8源码阅读(五) java.lang.CharSequence
  6. JDK8源码阅读(六) java.lang.String

注: 今年要把JDK的一些基本的类的源码整理出来,欢迎大家指正和讨论。

         如果有错误的地方,欢迎各位老师指正。

         如果您觉得还不错,点个赞的话  我会很感激的,谢谢~

         转载请注明链接来源即可。

 

 

 

 

 

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/17760.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!