SerialVersionUID

Java在反序列化时,会检查序列化字节流中的SerialVersionUID是否和本地类的SerialVersionUID一致,不一致会抛出InvalidClassException异常

SerialVersionUID有两种生成方法

  • 类中指明:private static final long serialVersionUID = 1L;

  • ObjectOutputStream#writeObject自动计算类的信息自动生成

调用ObjectOutputStream#writeObject(o)

ObjectOutputStream#writeClassDescriptor -> ObjectStreamClass#writeNonProxy -> ObjectStreamClass#getSerialVersionUID

void writeNonProxy(ObjectOutputStream out) throws IOException {
    out.writeUTF(name);
    out.writeLong(getSerialVersionUID()); //...
}

/**
     * Return the serialVersionUID for this class.  The serialVersionUID
     * defines a set of classes all with the same name that have evolved from a
     * common root class and agree to be serialized and deserialized using a
     * common format. NonSerializable classes have a serialVersionUID of 0L.
*/
public long getSerialVersionUID() {
    if (suid == null) {
        suid = AccessController.doPrivileged(
            new PrivilegedAction<Long>() {
                public Long run() {
                    return computeDefaultSUID(cl);
                }
            }
        );
    }
    return suid.longValue();
}

下面是serialVersionUID的计算方式

计算的内容如下:

  • 类名、类的访问修饰符、类的接口名

  • 非私有或私有非静态、非transient的字段名、访问修饰符、签名

  • 非私有构造器

  • 非私有方法

对这些数据进行SHA1哈希,再进行移位和与或运算

反射调用computeDefaultSUID来计算一个类的SerialVersionUID

Last updated

Was this helpful?