读书人

java对序列化serialVersionUID的处置分

发布时间: 2012-09-08 10:48:07 作者: rapoo

java对序列化serialVersionUID的处理分析

继上次分析了java的序列化过程之后,对于serialVersionUID的处理还不是很清晰,今天再看下代码,对serialVersionUID的处理进行了了解,上次的序列化过程分析可以参考另外一篇文章:http://zhwj184.iteye.com/blog/1550699

ObjectOutputStream.java调用writeObject的时候会调用到下面的代码:

这是调用ObjectStreamClass.java的writeNonProxy方法,写入非代理类的元数据信息

在写入类的元数据的时候会把serialVersionUID写入:


/**     * Initializes class descriptor representing a non-proxy class.     */    void initNonProxy(ObjectStreamClass model,       Class cl,       ClassNotFoundException resolveEx,      ObjectStreamClass superDesc)throws InvalidClassException    {this.cl = cl;this.resolveEx = resolveEx;this.superDesc = superDesc;name = model.name;suid = Long.valueOf(model.getSerialVersionUID());isProxy = false;isEnum = model.isEnum;serializable = model.serializable;externalizable = model.externalizable;hasBlockExternalData = model.hasBlockExternalData;hasWriteObjectData = model.hasWriteObjectData;fields = model.fields;primDataSize = model.primDataSize;numObjFields = model.numObjFields;if (cl != null) {    localDesc = lookup(cl, true);    if (localDesc.isProxy) {throw new InvalidClassException(    "cannot bind non-proxy descriptor to a proxy class");    }    if (isEnum != localDesc.isEnum) {throw new InvalidClassException(isEnum ?    "cannot bind enum descriptor to a non-enum class" :    "cannot bind non-enum descriptor to an enum class");    }        if (serializable == localDesc.serializable &&!cl.isArray() &&suid.longValue() != localDesc.getSerialVersionUID())    {throw new InvalidClassException(localDesc.name,     "local class incompatible: " +    "stream classdesc serialVersionUID = " + suid +    ", local class serialVersionUID = " +    localDesc.getSerialVersionUID());    }    if (!classNamesEqual(name, localDesc.name)) {throw new InvalidClassException(localDesc.name,    "local class name incompatible with stream class " +    "name \"" + name + "\"");    }        if (!isEnum) {if ((serializable == localDesc.serializable) &&    (externalizable != localDesc.externalizable)){    throw new InvalidClassException(localDesc.name, "Serializable incompatible with Externalizable");}if ((serializable != localDesc.serializable) ||    (externalizable != localDesc.externalizable) ||    !(serializable || externalizable)){    deserializeEx = new InvalidClassException(localDesc.name,"class invalid for deserialization");}    }        cons = localDesc.cons;    writeObjectMethod = localDesc.writeObjectMethod;    readObjectMethod = localDesc.readObjectMethod;    readObjectNoDataMethod = localDesc.readObjectNoDataMethod;    writeReplaceMethod = localDesc.writeReplaceMethod;    readResolveMethod = localDesc.readResolveMethod;    if (deserializeEx == null) {deserializeEx = localDesc.deserializeEx;    }}fieldRefl = getReflector(fields, localDesc);// reassign to matched fields so as to reflect local unshared settingsfields = fieldRefl.getFields();    }    

所以serialVersionUID在前后都不能做修改,否则会导致序列化失败。

读书人网 >软件架构设计

热点推荐