Serializable接口官方doc

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. 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.

类的可序列化由实现java.io.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. 

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


During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class.  A no-arg constructor must be accessible to the subclass that is serializable.  The fields of serializable subclasses will be restored from the stream.

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


When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object.

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


lasses that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

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


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


The writeObject method is responsible for writing the state of the object for its particular class so that the corresponding readObject method can restore it.  The default mechanism for saving the Object's fields can be invoked by calling out.defaultWriteObject. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

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


The readObject method is responsible for reading from the stream and restoring the classes fields. It may call in.defaultReadObject to invoke the default mechanism for restoring the object's non-static and non-transient fields.  The defaultReadObject method uses information in the stream to assign the fields of the object saved in the stream with the correspondingly named fields in the current object.  This handles the case when the class has evolved to add new fields. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

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


The readObjectNoData method is responsible for initializing the state of the object for its particular class in the event that the serialization stream does not list the given class as a superclass of the object being deserialized.  This may occur in cases where the receiving party uses a different version of the deserialized instance's class than the sending party, and the receiver's version extends classes that are not extended by the sender's version.  This may also occur if the serialization stream has been tampered; hence, readObjectNoData is useful for initializing deserialized objects properly despite a "hostile" or incomplete source stream.

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


Serializable classes that need to designate an alternative object to be used when writing an object to the stream should implement this special method with the exact signature:

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


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


 This writeReplace method is invoked by serialization if the method exists and it would be accessible from a method defined within the class of the object being serialized. Thus, the method can have private, protected and package-private access. Subclass access to this method follows java accessibility rules. 

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


Classes that need to designate a replacement when an instance of it is read from the stream should implement this special method with the exact signature.

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


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

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


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. 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 {@link InvalidClassException}.  A serializable class can declare its own serialVersionUID explicitly by declaring a field named <code>"serialVersionUID"</code> that must be static, final, and of type <code>long</code>:

序列化运行时将每个可序列化的类与称为serialVersionUID的版本号相关联,该序列号在反序列化期间用于验证序列化对象的发送者和接收者是否已加载与该序列化兼容的对象的类。 如果接收方加载了与对应发件人类不同的serialVersionUID的对象的类,则反序列化将导致{@link InvalidClassException}。 可序列化的类可以通过声明一个名为<code>“serialVersionUID”</ code>的字段来显式地声明自己的serialVersionUID,该字段必须是static,final和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.  However, it is <em>strongly recommended</em> 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 <code>InvalidClassException</code>s during deserialization.  Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value.  It is also strongly advised that explicit serialVersionUID declarations use the <code>private</code> modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.
如果可序列化类没有显式声明serialVersionUID,则序列化运行时将根据Java(TM)对象序列化规范中所述的类的各个方面计算该类的默认serialVersionUID值。但是,强烈建议所有可序列化的类都明确声明serialVersionUID值,因为默认的serialVersionUID计算对类细节非常敏感,这可能会因编译器实现而异,因此可能导致意外的<code> InvalidClassException </ code>反序列化。因此,为了保证不同Java编译器实现之间的一致的serialVersionUID值,一个可序列化的类必须声明一个显式的serialVersionUID值。还强烈建议,显式的serialVersionUID声明在可能的情况下使用私有修饰符,因为这样的声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无效。数组类不能声明一个显式的serialVersionUID,所以它们总是具有默认的计算值,但是对于数组类,放弃了匹配serialVersionUID值的要求。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值