Java序列化魔术方法及其示例使用

在上一篇文章中, 您需要了解有关Java序列化的所有知识 ,我们讨论了如何通过实现Java序列化来启用类的可序列化性。
Serializable接口。 如果我们的类未实现Serializable接口,或者该类具有对非Serializable类的引用,则JVM将抛出NotSerializableException

可序列化类的所有子类型本身都是可序列化的,并且
Externalizable接口还扩展了可序列化。 所以即使我们
使用Externalizable自定义序列化过程,我们的类仍然是 Serializable

Serializable接口是一个没有方法或字段的标记接口,它的作用类似于JVM的标志。 ObjectInputStreamObjectOutputStream类提供的Java序列化过程完全由JVM控制。

但是,如果我们想添加一些其他逻辑来增强此正常过程,例如,我们可能希望在对敏感信息进行序列化/反序列化之前对其进行加密/解密。 Java为此提供了一些其他方法,我们将在此博客中讨论。

writeObject和readObject方法

希望自定义或添加一些其他逻辑以增强常规序列化/反序列化过程的可序列化类应提供
具有以下确切签名的writeObjectreadObject方法:

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

在Java序列化您需要了解的一切文章下,已经对这些方法进行了详细讨论。

readObjectNoData方法

Serializable类的Java文档所述,如果我们要在序列化流未将给定类列出为要反序列化的对象的超类的情况下初始化其特定类的对象状态,则应提供writeObject和具有以下确切签名的readObject方法:

  • private void readObjectNoData() throws ObjectStreamException

在接收方使用与发送方不同的反序列化实例类的版本,并且接收方的版本扩展了发送方的版本未扩展的类的情况下,可能会发生这种情况。 如果序列化流已被篡改,也会发生这种情况。 因此,尽管源流“充满敌意”或不完整,但readObjectNoData对于正确初始化反序列化的对象很有用。

每个可序列化的类都可以定义自己的readObjectNoData方法。 如果可序列化的类未定义readObjectNoData方法,则在上述情况下,该类的字段将被初始化为其默认值。

writeReplace和readResolve方法

将对象写入流时需要指定要使用的替代对象的可序列化类应为此特殊方法提供确切的签名:

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

当从流中读取实例时,需要指定替换的Serializable类应为此特殊方法提供确切的签名:

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

基本上, writeReplace方法允许开发人员提供将被序列化的替换对象,而不是原始对象。 在反序列化过程中使用了readResolve方法,用我们选择的另一个方法来替换反序列化的对象。

writeReplace和readResolve方法的主要用途之一是使用Serialized类实现单例设计模式。 我们知道, 反序列化过程每次都会创建一个新对象 ,它也可以用作深度克隆对象的方法,如果我们必须使类为单例,那么这样做就不好了。


您可以在Java Cloning和Java上阅读有关Java克隆和序列化的更多信息。
Java序列化主题。


readObject返回之后调用readResolve方法(相反,在writeObject之前(可能在另一个对象上)调用writeReplace )。 该对象在方法返回替换this返回到的用户对象ObjectInputStream.readObject并流中的对象中的任何进一步的反向引用。 我们可以使用writeReplace方法将序列化对象替换为null,以便不进行序列化,然后使用readResolve方法将反序列化的对象替换为单例实例。

validateObject方法

如果我们想在某些字段上执行某些验证,则可以通过实现ObjectInputValidation接口并重写
来自它的validateObject方法。

当我们通过从readObject方法调用ObjectInputStream.registerValidation(this, 0)注册此验证时,将自动调用validateObject方法。 在将数据流交还给您的应用程序之前,验证数据流是否受到篡改或数据有意义是非常有用的。

下面的示例涵盖了上述所有方法的代码

 public class SerializationMethodsExample { public static void main(String[] args) throws IOException, ClassNotFoundException { Employee emp = new Employee( "Naresh Joshi" , 25 ); System.out.println( "Object before serialization: " + emp.toString()); // Serialization serialize(emp); // Deserialization Employee deserialisedEmp = deserialize(); System.out.println( "Object after deserialization: " + deserialisedEmp.toString()); System.out.println(); // This will print false because both object are separate System.out.println(emp == deserialisedEmp); System.out.println(); // This will print false because both `deserialisedEmp` and `emp` are pointing to same object, // Because we replaced de-serializing object in readResolve method by current instance System.out.println(Objects.equals(emp, deserialisedEmp)); } // Serialization code static void serialize(Employee empObj) throws IOException { try (FileOutputStream fos = new FileOutputStream( "data.obj" ); ObjectOutputStream oos = new ObjectOutputStream(fos)) { oos.writeObject(empObj); } } // Deserialization code static Employee deserialize() throws IOException, ClassNotFoundException { try (FileInputStream fis = new FileInputStream( "data.obj" ); ObjectInputStream ois = new ObjectInputStream(fis)) { return (Employee) ois.readObject(); } }  }  Employee class implements Serializable, ObjectInputValidation { private static final long serialVersionUID = 2L; private String name; private int age; public Employee(String name, int age) { this .name = name; this .age = age; } // With ObjectInputValidation interface we get a validateObject method where we can do our validations. @Override public void validateObject() { System.out.println( "Validating age." ); if (age < 18 || age > 70 ) { throw new IllegalArgumentException( "Not a valid age to create an employee" ); } } // Custom serialization logic, // This will allow us to have additional serialization logic on top of the default one eg encrypting object before serialization. private void writeObject(ObjectOutputStream oos) throws IOException { System.out.println( "Custom serialization logic invoked." ); oos.defaultWriteObject(); // Calling the default serialization logic } // Replacing de-serializing object with this, private Object writeReplace() throws ObjectStreamException { System.out.println( "Replacing serialising object by this." ); return this ; } // Custom deserialization logic // This will allow us to have additional deserialization logic on top of the default one eg performing validations, decrypting object after deserialization. private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { System.out.println( "Custom deserialization logic invoked." ); ois.registerValidation( this , 0 ); // Registering validations, So our validateObject method can be called. ois.defaultReadObject(); // Calling the default deserialization logic. } // Replacing de-serializing object with this, // It will will not give us a full proof singleton but it will stop new object creation by deserialization. private Object readResolve() throws ObjectStreamException { System.out.println( "Replacing de-serializing object by this." ); return this ; } @Override public String toString() { return String.format( "Employee {name='%s', age='%s'}" , name, age); }  } 

您可以在此找到本文的完整源代码。
Github存储库 ,请随时提供宝贵的反馈。

翻译自: https://www.javacodegeeks.com/2019/09/java-serialization-magic-methods-and-their-uses-with-example.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

针对新手的Java EE7和Maven项目-第2部分-为我们的应用程序定义一场简单的战争

从第一部分恢复 第1部分 我们刚刚定义了父 pom。 一种特殊的pom类型&#xff0c;它最终定义了我们的应用程序将要使用的库。 它还配置了所有用于包装我们应用程序每个模块的Maven工具。 您可以在此处 签出 -1部分示例代码。 因此&#xff0c;到目前为止&#xff0c;在将要开发…

电信级E1保护倒换设备产品介绍

1-8路E1倒换保护设备是由杭州飞畅科技有限公司自主研发生产的E1线路无损伤自动切换设备。本系列设备是本公司研制的专用超大规模集成电路的基础上开发的E1切换器。提供1-8路独立的E1倒换保护功能(816E1)&#xff0c;在默认工作方式下&#xff0c;主用E1线路出现故障时&#xff…

电话光端机的电话业务不通问题,该怎么去检查?

我司的设备&#xff0c;电话光端机都是达到电信级别&#xff0c;通话声音是特别清晰的。如果电话光端机的电话杂音声过大可能是电话光端机的光口有误码引起的。 一般应该是光端机有误码引起的&#xff0c;产生误码的原因主要是光纤部分&#xff0c;因为一般设备一般发货前&…

java8 camel_Meet Fabric8:基于Camel和ActiveMQ的开源集成平台

java8 camel面料8 Fabric8是来自Red Hat的JBoss Fuse产品的Apache 2.0许可上游社区。 这是一个基于Apache ActiveMQ &#xff0c; Camel &#xff0c; CXF &#xff0c; Karaf &#xff0c; HawtIO等的集成平台。 它提供了自动化的配置和部署管理&#xff0c;以帮助使部署变得…

电话光端机的电话接口类型有哪些?

电话光端机常用的的电话接口类型有&#xff1a;环路中继接口&#xff08;FXO&#xff09;、模拟用户线接口&#xff08;FXS&#xff09;、热线电话接口&#xff08;公务电话&#xff09;、磁石电话接口。接下来&#xff0c;我们就跟随飞畅科技的小编来详细了解下电话光端机的电…

如何使用可外部化的接口在Java中自定义序列化

在上一篇文章“用示例介绍的有关Java序列化的一切”中 &#xff0c;我解释了如何使用以下方法序列化/反序列化一个对象 Serializable接口&#xff0c;还说明了如何使用writeObject和readObject方法自定义序列化过程。 Java序列化过程的缺点 但是&#xff0c;这些定制还不够&a…

电话光端机使用什么光纤网络比较好?

电话光端机是一种将传统电话信号转换为光信号并通过光纤传输的设备&#xff0c;要使用电话光端机&#xff0c;必须首先具有光纤网络。那么电话光端机使用哪种纤维更好呢&#xff1f;接下来就让我们跟随飞畅科技的小编一起来看看吧&#xff01; 如果电话光端机使用的光纤网络在…

电话光端机原理及作用分析

常用的光端机分为多种类型&#xff0c;例如电话光端机、网络光端机、音频光端机、视频光端机、串口光端机、PDH光端机等。通常&#xff0c;电话光端机是最常用的&#xff0c;并且它们也被广泛使用。今天&#xff0c;就由光端机专业厂家飞畅科技来为大家普及下电话光端机的原理及…

关于Jakarta EE与MicroProfile的创新和关系的提案

在JCrete非会议上&#xff0c;我们中的一些人正在就Jakarta EE的愿景&#xff0c;尤其是与MicroProfile的关系进行头脑风暴。 我想开始讨论&#xff0c;以使所有人都在同一页面上&#xff0c;尤其是Jakarta EE和MicroProfile之间的关系以及Jakarta的创新应如何。 我相信我们中的…

电话光端机作用,电话光端机功能特点介绍

电话光端机顾名思义其实也是一种光端机&#xff0c;但是他不仅仅只能传输电话的光端机。它的用户接口类型多样&#xff08;包括语音、数据、图象&#xff09;&#xff0c;均以小型模块化部件方式装配到母板上&#xff0c;各种用户模块可以混合装配&#xff0c;方便扩容及维护。…

光端机的作用是什么? 简述光端机的作用

简单说光端机是光信号传输的终端设备&#xff0c;光端机一般都是成对使用&#xff0c;分为光发射机和光接收机。市面上常见的光端机主要有&#xff1a;电话光端机、PDH光端机、高清视频光端机、音频光端机、以太网光端机、数据光端机等等。那么&#xff0c;各类光端机的作用是什…

db2分页sql_停止尝试使用内部DB框架模拟SQL OFFSET分页!

db2分页sql我敢肯定&#xff0c;到目前为止&#xff0c;您已经以多种方式弄错了。 而且您可能很快将无法正确处理。 那么&#xff0c;当您可以实施业务逻辑时&#xff0c;为什么还要在SQL调整上浪费您的宝贵时间呢&#xff1f; 让我解释… 直到最近的SQL&#xff1a;2008标准 …

关于单纤与双纤光端机的区别介绍

单纤和双纤的光端机最大区别就是它们主板上的光模块区别&#xff0c;其他的地方基本上都是一样的。下面&#xff0c;飞畅科技的小编来为大家详细介绍下单纤与双纤光端机的区别&#xff0c;一起来看看吧&#xff01; 单纤光端机&#xff1a;接收与发送的数据在一根光纤上传输。…

ImportError: cannot import name ‘constants‘

运行ns3gym案例一直报这个错&#xff0c;然后重新配置了两遍环境&#xff0c;然而并没有什么用。通过Google Baidu搜索&#xff0c;建议执行以下代码 pip install --upgrade pyzmq 执行后出现以下错误 然后搜索执行代码 sudo pip3 install --ignore-installed pyzmq 安装成功…

如何在不同的浏览器中设置Selenium网格以并行执行

到目前为止&#xff0c;Selenium是最常用的Web自动化测试工具。 如此受欢迎的原因之一是Selenium的自动跨浏览器测试功能。 硒自动化测试可以帮助您在所有主要浏览器&#xff0c;所有主要操作系统甚至移动设备浏览器上进行测试。 您可以在所有功能测试中获得广泛的浏览器覆盖&a…

网管型工业交换机和 非网管型工业交换机的优缺点

工业交换机专业为达到灵便变化多端的工业生产运用要求而设计方案&#xff0c;出示一种性价比高电力线通信通讯解决方法。而工业交换机也分成网管型和非网管型二种。那么&#xff0c;网管型工业交换机和非网管型工业交换机有什么不同&#xff0c;大家该如何选择呢&#xff1f;接…

如何集成和使用EclEmma插件来获得良好的Junit覆盖率

你好朋友&#xff0c; 如果编写好的代码很重要&#xff0c;那么编写覆盖所有业务逻辑的优良Junit测试用例也同样重要。通过编写覆盖业务逻辑的Junit测试用例&#xff0c;我们实际上确保代码的每种方法都能正常工作按照预期进行&#xff0c;因此减少了在软件开发的后期阶段中获…

工业4.0时代,工业交换机在智能电网建设中有什么作用?

随着工业以太网技术、光纤技术和信息处理技术的发展&#xff0c;并向电力行业的渗透&#xff0c;在当前技术条件支持下&#xff0c;工业以太网通信在运行过程中表现出高可靠性、灵活性和扩展性等优点&#xff0c;对优化整个电网系统设备元件之间的连接和信息传输有着重要的作用…

工业交换机的性能优势有哪些?

工业交换机也称作工业以太网交换机&#xff0c;即应用于工业控制领域的以太网交换机设备&#xff0c;对工业交换机我们有多少人了解呢&#xff1f;究竟何为工业交换机&#xff0c;工业交换机有哪些功能呢&#xff1f;接下来就由飞畅科技的小编来为大家详细讲解下吧&#xff01;…

谷歌浏览器出现“远程计算机访问失败问题”

转载链接 一、进入浏览器设置 二、“internet选项”目录 三、设置 只勾选一个&#xff0c;其余均不选。 四、打开新网页&#xff0c;解决问题