本文主要要看看JDK中使用Serializable和Externalizable接口来完成Java对象序列化,并给出部分属性序列化的几种方式,最终做出Serializable和Externalizable 注:本文不讨论为什么不用第三方工具包完成序列化等~ 一、序列化Serializable 要实现Java对象的序列化, 只要将类实现Serializable或Externalizable接口即可。 = null); 2.3 使用Externalizable实现 还有一种方式,就是使用Externalizable完成部分属性的序列化。 Externalizable继承自Serializable,使用Externalizable接口需要实现writeExternal以及readExternal方法~在writeExternal方法中,写入想要外部序列化的元素 【3】Externalizable接口的实现方式一定要有默认的无参构造函数~ ?
本篇文章我们来聊一聊Java中的Serializable和Externalizable。 大索:小码、没人理,你们知道Java中的Serializable(可序列化)和Externalizable(可外部化)吗? 小码:Externalizable? 大索:孺子可教也。通过实现Externalizable接口,给我们提供了实现序列化逻辑的机会。 Externalizable接口提供对序列化过程的控制,它实现了Serializable接口。 Externalizable接口提供对过程的完全控制,并可用于提高性能。 Serializable和Externalizable接口都用于对象序列化。
Externalizable 的序列化机制优先级要高于 Serializable 。 Externalizable 源码分析 ? 从源码中,我们可以看到 Externalizable 接口继承了 Serializable 接口。 并定义了两个方法 writeExternal 和 readExternal 方法 Externalizable 示例一 User 类 public class User implements Externalizable 当执行 Test.main() 方法,执行的结果如下: User [userName=zhangsan, password=externalizable:123456] 可以看出,执行的是 Externalizable 结论二 Externalizable 序列化的优先级比Serializable的优先级高。
1.代码 Demo3测试类 /* * zt * 2020/8/8 * 15:34 *序列化:把Person对象写入硬盘中 要求:1.序列化的类必须是Serializable自动或者Externalizable 能 , 使用 Externalizable 实现。 } System.out.println(Person.country); ois.close(); } } Person类 import java.io.Externalizable java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class Person implements Externalizable
Externalizable接口实现序列化与反序列化 package com.example.core.mydemo.java; import com.example.core.mydemo.json2 .GsonUtils; import java.io.*; /** * Externalizable接口实现序列化与反序列化 * * Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程 * * Externalizable接口继承Serializable接口,实现Externalizable接口需要实现readExternal()方法和writeExternal()方法,这两个方法是抽象方法 } } package com.example.core.mydemo.java; import java.io.*; public class Person2 implements Externalizable
只用于标记该对象可序列化;若未实现该接口,则序列化时会报NotSerializableException异常 自定义序列化方式 在对象中重写 writeObject 和 readObject 方法 实现Externalizable 该常数用于指定对象的版本,反序列化时会检查版本是否改变,若改变则会报错 建议显示赋值该常量,否则jvm会根据对象属性、方法等自动生成,若序列化前后对象有变化,则版本号会重新生成,反序列化时就会抛异常 Externalizable Externalizable 序列化的优先级比Serializable的优先级高 使用 Externalizable 进行序列化时,必须要有默认的构造方法,而Serializable可以没有默认的构造方法 这是因为使用 Externalizable 进行反序列化时,需要有默认的构造方法,通过反射先创建出该类的实例,然后再把解析后的属性值,通过反射赋值 其他注意事项 静态变量不会被序列化 transient developer/article/1130025 https://www.baeldung.com/java-serialization https://www.baeldung.com/java-externalizable
Java中还提供了Externalizable接口,也可以实现它来提供序列化能力。 Externalizable继承自Serializable,该接口中定义了两个抽象方法:writeExternal()与readExternal()。 备注: Externalizable接口和Serializable接口的区别: Externalizable继承了Serializable,该接口中定义了两个抽象方法:writeExternal()与 当使用Externalizable接口来进行序列化与反序列化的时候需要开发人员重写writeExternal()与readExternal()方法。 所以,实现Externalizable接口的类必须要提供一个public的无参的构造器。
接口实现序列化 Externalizable 继承自 Serializable 接口,需要我们重写 writeExternal() 与 readExternal() 方法来决定要序列化哪些信息,并且必须要提供一个 Externalizable 的性能要优于 Serializable,但也增加了复杂性。 @Data public class UserB implements Externalizable { /** * 序列化ID */ private static 要想将父类对象也序列化,就需要让父类也实现 Serializable(或 Externalizable) 接口。 引用类型成员变量的序列化。 要想引用对象也序列化,就需要让引用对象也实现 Serializable(或 Externalizable) 接口。
序列化相关文章: Java 序列化 之 Serializable Java 序列化之 Externalizable Java 序列化 之 单例模式。 阅读本文章之前,务必要阅读上面的三篇文章。 1、检查是否可以序列化 2、写入类型 3、写 class 的描述信息 4、判断是 该对象 否实现了 Externalizable 接口 如果实现了则调用 writeExternalData 方法。 这里,我们可以看到,如果实现了 Externalizable 接口,会优先执行 Externalizable 接口的实现的方法,而默认的序列化方法不会执行。 这里也解释了上一篇文章中Java 序列化之 Externalizable 示例三 的原因。 writeExternalData 方法 实现 Externalizable 序列化接口 ? 1、判断该类是否实现了 Externalizable 接口,如果实现了Externalizable 接口,就执行readExternalData () 方法 2、否则,执行 readSerialData
而使用Externalizable则是调用一个无参构造方法来实例化,原因如下: Externalizable序列化的过程:使用Externalizable序列化时,在进行反序列化的时候,会重新实例化一个对象 (model.serializable || model.externalizable)) {//如果一个类既没实现serializable,也没实现externalizable,则给该类的描述对象的成员变量 而使用Externalizable是通过调用一个无参构造方法来实例化。 本质上两种方式都是使用类构造器来完成实例化,相对于Externalizable必须要求类实现无参构造器,Serializable放开了这一限制,在一定程度上适用性强于Externalizable,但仍然要求其未实现 另一方面,实现 Externalizable 接口能带来较大的时间及空间的性能提升(相比于Serializable需要构造新的构造器等复杂逻辑,具体参见几种序列化协议的介绍),但由于实现 Externalizable
---- java.io.Externalizable Interface 在序列化中,Java虚拟机完全负责写入和读取对象的过程。 因此,Externalizable是为了让程序员在序列化期间对对象的读写进行完全控制。 Serializable有一个Externalizable的子接口,如果要自定义类的序列化方式,可以使用它。 当Externalizable的一个实例传递给ObjectOutputStream时,会绕过默认的序列化过程,会用实例的writeExternal()方法。 这给出了我们如何通过实现Externalizable接口来控制序列化过程的想法。 这给了我们通过实现Externalizable接口来控制反序列化过程的想法。
为了了解Externalizable接口和Serializable接口的区别先来看代码,我们将上面的User1类改为实现java.io.Externalization接口; package common.lang 当使用Externalizable接口来进行序列化与反序列化的时候需要开发人员重写writeExternal()与readExternal()方法。 还有一点值得注意:在使用Externalizable进行序列化的时候,在读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。 所以,实现Externalizable接口的类必须要提供一个public的无参的构造器。 按照要求修改之后的代码是: package common.lang; import java.io.Externalizable; import java.io.IOException; import
Externalizable接口:其实呀,除了 Serializable 之外,Java 还提供了一个序列化接口 Externalizable,它是Serializable的子接口,使用 Externalizable 进行反序列化的时候,会调用被序列化类的无参构造方法去创建一个新的对象,然后再将被保存对象的字段值复制过去;实现Externalizable接口时,必须重写其中的writeExternal() 和 readExternal 适应场景: 因为Externalizable接口拥有着更高的序列化控制能力,所以在序列化过程中,我们需要对一些敏感信息进行加密处理时,它的作用就会体现啦。 我们使用这个接口进行序列化尝试,并且使用transient关键字修饰字段,看一下结果:public class Test implements Externalizable { private transient 四、总结通过上面的学习,我们知道了在Java的序列化中有 Serializable、Externalizable这两个接口,前者没有任何方法,只是一个标识,而后者作为子类,提供了必须重写的方法,用以自定义序列化设计
第二种 实现Externalizable接口。 Externalizable接口是继承自Serializable接口的,我们在实现Externalizable接口时,必须实现writeExternal(ObjectOutput)和readExternal Externalizable ? Externalizable结果 反序列化时,首先会调用对象的默认构造器(没有则报错,如果默认构造器不是public的也会报错),然后再调用readExternal方法。
Serializable和Externalizable的区别 最后我们讲下Externalizable和Serializable的区别。 Externalizable继承自Serializable,它需要实现两个方法: void writeExternal(ObjectOutput out) throws IOException; 而Externalizable则完全需要我们自己来控制如何写/读,比较麻烦,但是如果考虑性能的话,则可以使用Externalizable。 另外Serializable进行反序列化不需要执行构造函数。 而Externalizable需要执行构造函数构造出对象,然后调用readExternal方法来填充对象。所以Externalizable的对象需要一个无参的构造函数。 总结 本文详细分析了序列化对象在多种情况下的使用,并讲解了Serializable和Externalizable的区别,希望大家能够喜欢。
三、Externalizable接口 在使用Externalizable接口的类前,先要实现writeExternal和readExternal方法,这两个方法用于自定义对象的序列化和反序列化过程。 import java.io.*; class MyClass implements Externalizable { int i; int j; @Override
JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。 ? ? ? ? ? Externalizable进行序列化,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。 由于这个原因,实现Externalizable接口的类必须要提供一个无参的构造器,且它的访问权限为public。 7 单列模式进行序列化,那还是单例吗? ? ? ? 4.Externalizable接口如何实现。 5.序列化会破坏单例模式。
/** * Returns true if represented class is serializable/externalizable and can * be instantiated by the serialization runtime--i.e., if it is * externalizable and defines a public no-arg constructor, or if it is * non-externalizable and its first non-serializable superclass defines an * accessible = null); } 这段代码吧注释也贴出来了,可以看到这个方法的作用是:如果这个类是实现了serializable/externalizable,并且可以由序列化运行时实例化,则返回true,其他情况 = Externalizable.class.isAssignableFrom(cl); Class<?
public interface Serializable {} Externalizable 接口 Externalizable继承了Serializable接口,还定义了两个抽象方法:writeExternal ()和readExternal(),如果开发人员使用Externalizable来实现序列化和反序列化,需要重写writeExternal()和readExternal()方法 public interface 在 Java 中,Serializable 和 Externalizable 有什么区别 serialVersionUID有什么用? 3.在Java中,Serializable 和 Externalizable 有什么区别 Externalizable继承了Serializable,给我们提供 writeExternal() 和 readExternal 正确实现 Externalizable 接口可以显著提高应用程序的性能。 4.serialVersionUID有什么用?
实现序列化的要求 只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。 JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效,此时使用该接口时,序列化的细节需要由程序员去完成。 public class Person implements Externalizable { private String name =null; transientprivateInteger 另外,使用Externalizable进行序列化时,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。 由于这个原因,实现Externalizable接口的类必须要提供一个无参的构造器,且它的访问权限为public。