简体   繁体   English

超级类和子类的序列化

[英]Serialization with Super class and Sub class

My doubt is using Scenario 1 it is possible to achieve serialization . 我的疑问是使用方案1是否有可能实现序列化。 If I extend one abstract class which is serializable by many sub classes means , is this possible to achieve ?. 如果我扩展了一个抽象类,该抽象类可以通过许多子类的方式进行序列化,那有可能实现吗? As I tried with Scenario 2. 正如我在场景2中尝试的那样。

Serializable will be applicable for all beans or not,Please help me. 可序列化是否适用于所有bean,请帮助我。

my doubt scenario 1 and scenario 2 will be same or different. 我怀疑方案1和方案2相同还是不同。

//method to send message ::: sendMsgs(SerializableObject) //发送消息的方法::: sendMsgs(SerializableObject)

Scenario 1: 方案1:

public class EmailMaster implements Serializable 
{
// setters and getters
}

Scenario 2: 方案2:

public abstract class MessageBean implements Serializable 
{ 
}

//whether EmailMaster and EmailEvent  will become serializable ?

public class EmailMaster extends MessageBean 
{
// setters and getters



public class EmailEvent extends MessageBean 
{
// setters and getters
}

This should be Serialilzable . 这应该是Serialilzable When you extend MessageBean , all extending classes of MessageBean be default inherit the Serializable interface from MessageBean abstract class. 扩展MessageBean ,默认情况下,所有扩展的MessageBean类都是继承自MessageBean抽象类的Serializable接口。

I would advice to have unique serialVersionUID assigned in each extending(sub) classes. 我建议在每个extending(sub)类中分配唯一的serialVersionUID

EDIT: From Searialization perspective, scenario1 and sceanrio2 are not different but theoretically they are different as you are having an additional abstract class in sceario2 , which can have more methods/attributes, which will also get available to the EmailMaster class. 编辑:从Searialization角度来看, scenario1sceanrio2并没有什么不同,但是从理论上讲它们是不同的,因为您在sceario2中有一个附加的抽象类,它可以具有更多的方法/属性,这些内容也可以用于EmailMaster类。

In both the scenarios: sendMsgs(SerializableObject) should work. 在这两种情况下: sendMsgs(SerializableObject)应该起作用。 Make a decision between sceanrio1 and scenario2 based on the need of abstract class in between. 根据介于两者之间的抽象类的需求,在sceanrio1和case2之间做出决定。 If you don't need the abstract class for any other purpose, go with scenario1. 如果您不需要抽象类用于任何其他目的,请使用scenario1。

Serializable is inherited by all the subclasses of the abstract class as for any other interface: 像其他任何接口一样,可Serializable由抽象类的所有子类继承:

If A implements Serializable , whatever class extends A will be Serializable 如果A实现Serializable ,则扩展A的任何类都将是Serializable

So both Scenarios will work but in any case a concrete Serializable class must have a no-args constructor . 因此,这两种方案都可以使用,但无论如何,具体的Serializable类必须具有no-args构造函数 See the following Serializable Javadoc : 请参阅以下可序列化的Javadoc

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. 通过实现java.io.Serializable接口的类,可以启用类的可序列化性。 Classes that do not implement this interface will not have any of their state serialized or deserialized. 未实现此接口的类将不会对其状态进行序列化或反序列化。 All subtypes of a serializable class are themselves serializable. 可序列化类的所有子类型本身都是可序列化的。 The serialization interface has no methods or fields and serves only to identify the semantics of being serializable. 序列化接口没有方法或字段,仅用于标识可序列化的语义。

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. 为了允许不可序列化类的子类型被序列化,该子类型可以负责保存和恢复超类型的公共,受保护和(如果可访问)程序包字段的状态。 The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state . 仅当其扩展的类具有可访问的无参数构造函数来初始化类的状态时,该子类型才可以承担此责任 It is an error to declare a class Serializable if this is not the case. 如果不是这样,则声明一个可序列化的类是错误的。 The error will be detected at runtime. 该错误将在运行时检测到。

Moreover, regarding the Serial Version ID of the object: 此外,关于对象的Serial Version ID

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization . 序列化运行时与每个可序列化的类关联一个版本号,称为serialVersionUID,在反序列化期间使用该版本号来验证序列化对象的发送者和接收者是否已加载了该对象的与序列化兼容的类 If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. 如果接收方已为该对象加载了一个与相应发送方类具有不同的serialVersionUID的类,则反序列化将导致InvalidClassException。 A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long: 可序列化的类可以通过声明一个名称为“ serialVersionUID”的字段来显式声明其自己的serialVersionUID,该字段必须是静态的,最终的且类型为long:

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

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification . 如果可序列化的类未显式声明serial_VersionUID,则序列化运行时将根据该类的各个方面,为该类计算默认的serialVersionUID值,如Java(TM)对象序列化规范中所述 However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. 但是,强烈建议所有可序列化的类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类详细信息高度敏感,而类详细信息可能会根据编译器的实现而有所不同,因此可能在反序列化期间导致意外的InvalidClassExceptions。

Try 尝试

Serializable emailMaster = new EmailMaster();

If it works then EmailMaster is-a Serializable . 如果有效,则EmailMaster 是-可 Serializable AFAIK, that definitely should work. AFAIK,那绝对应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM