Java基础篇

来源:互联网 发布:超人软件站 编辑:程序博客网 时间:2024/06/08 16:26

一直觉得学习一手的知识,能更好的理解一些问题的来龙去脉,本文对Java文档中Serializable与serialVersionUID相关的描述进行了粗略的翻译,以帮助大家更好的理解。


原文: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.

译文:如需对非序列化类的子类进行序列化,子类需要拓展了一个可见的无参构建函数进行该类状态的初始化(即承担保存与恢复父类中所有public、protected及package作用域变量的责任)。否则,在运行时将报错。


原文: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.

译文:在反序列化过程中,不可序列化类的变量将使用该类的公共或受保护的无参数构造函数来初始化。无参数构造函数必须可以被可序列化的子类访问。可序列化子类的字段将从流中恢复。


原文: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.

译文:进行遍列时,可能会遇到不支持可序列化接口的类。在这种情况下,将抛出NotSerializableException用以标识该类的不可序列化的对象。


原文:Classes 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方法。因此,该方法可以具有私有,受保护和包私有访问。子类对此方法的访问遵循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;
 

原文:This readResolve method follows the same invocation rules and accessibility rules as writeReplace.

译文:此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 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不同于对应的发送者类的serialVersionUID,那么反序列化将导致InvalidClassException。 可序列化类可以通过声明一个名为“serialVersionUID”的字段来显式声明它自己的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 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. 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 private 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,则串行化运行时将基于类的各个方面计算该类的默认serialVersionUID值,如Java(TM)对象序列化规范中所述。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为缺省的serialVersionUID计算对类详细信息非常敏感,可能会因编译器实现而异,因此可能会导致反序列化期间出现意外的InvalidClassExceptions。因此,为了确保不同Java编译器实现中的serialVersionUID值一致,可序列化类必须声明一个显式的serialVersionUID值。还强烈建议,显式serialVersionUID声明在可能的情况下使用private修饰符,因为这样的声明仅适用于立即声明的类 - serialVersionUID字段不作为继承成员使用。数组类不能声明显式serialVersionUID,因此它们总是具有默认计算值,但对于数组类,可以不需要匹配serialVersionUID值。

0 0
原创粉丝点击