如果我们要把一个对象序列化,必须要实现Serializable接口
这个Serializable接口相当于一个标识,表示实现了该接口的对象允许序列化。
但是我们实现了Serializable接口后,还要在该对象中加一个字段serialVersionUID
如:
public class User implements Serializable {
private final static Long serialVersionUID = 1235L;
private String name;
// 其他字段
......
}
很多人在实现Serializable 不加serialVersionUID字段,但是这可能会导致反序列化失败!
我们可以从源码来看
/**
* ......
* 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>:
*
* <PRE>
* ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
* </PRE>
*
* 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.
*
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}
如果可序列化类未显式声明 serialVersionUID,则序列化运行时将根据该类的各个方面计算该类的默认 serialVersionUID 值,但是默认对 serialVersionUID的 计算对可能因编译器实现而不同。
反序列化时,如果serialVersionUID不相同,会抛出InvalidClassException导致反序列化失败。
所以,我们在实现Serializable接口后,都要在可序列化类显示声明serialVersionUID。
并且serialVersionUID的定义必须是 long final static
。 建议使用 private
修饰。