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在前后都不能做修改,否则会导致序列化失败。