作者:沉默王二
来源:CSDN
原文:https://blog.csdn.net/qing_gee/article/details/93176705
版权声明:本文为博主原创文章,转载请附上博文链接!
private void defaultWriteFields(Object obj, ObjectStreamClass desc)
throws IOException
{
Class> cl = desc.forClass();
desc.checkDefaultSerialize();
int primDataSize = desc.getPrimDataSize();
desc.getPrimFieldValues(obj, primVals);
bout.write(primVals, 0, primDataSize, false);
ObjectStreamField[] fields = desc.getFields(false);
Object[] objVals = new Object[desc.getNumObjFields()];
int numPrimFields = fields.length - objVals.length;
desc.getObjFieldValues(obj, objVals);
for (int i = 0; i < objVals.length; i++) {
try {
writeObject0(objVals[i],
fields[numPrimFields + i].isUnshared());
}
}
}
ObjectInputStream 为例,它在反序列化的时候会依次调用 readObject()→readObject0()→readOrdinaryObject()→readSerialData()→defaultReadFields()。
private void defaultWriteFields(Object obj, ObjectStreamClass desc)
throws IOException
{
Class> cl = desc.forClass();
desc.checkDefaultSerialize();
int primDataSize = desc.getPrimDataSize();
desc.getPrimFieldValues(obj, primVals);
bout.write(primVals, 0, primDataSize, false);
ObjectStreamField[] fields = desc.getFields(false);
Object[] objVals = new Object[desc.getNumObjFields()];
int numPrimFields = fields.length - objVals.length;
desc.getObjFieldValues(obj, objVals);
for (int i = 0; i < objVals.length; i++) {
try {
writeObject0(objVals[i],
fields[numPrimFields + i].isUnshared());
}
}
}
定义为空 起标识作用
开门见山的说吧,static 和 transient 修饰的字段是不会被序列化的。
private static ObjectStreamField[] getDefaultSerialFields(Class> cl) {
Field[] clFields = cl.getDeclaredFields();
ArrayList list = new ArrayList<>();
int mask = Modifier.STATIC | Modifier.TRANSIENT;
int size = list.size();
return (size == 0) ? NO_FIELDS :
list.toArray(new ObjectStreamField[size]);
}
使用 Externalizable 进行反序列化的时候,会调用被序列化类的无参构造方法去创建一个新的对象,然后再将被保存对象的字段值复制过去。否则的话,会抛出以下异常:
新增了两个方法 writeExternal() 和 readExternal(),实现 Externalizable 接口所必须的
serialVersionUID 被称为序列化 ID,它是决定 Java 对象能否反序列化成功的重要因子。在反序列化时,Java 虚拟机会把字节流中的 serialVersionUID 与被序列化类中的 serialVersionUID 进行比较,如果相同则可以进行反序列化,否则就会抛出序列化版本不一致的异常。
就Serializable接口来说,类要去实现序列化有很大的代价,虽然只是简单的实现了这个这么一个标识接口,主要在于:
一旦这个类实现了序列化接口,假如被发布使用,就大大降低了“改变这个类的实现”的灵活性. 因为这个类的字节流编码就变成了它导出API的一部分,一旦这个类被广泛使用,必须的保持这样的形式。使得类的演变收到限制,比如它和序列号UID有直接关系
增加了出现bug和安全漏洞的可能性
使得测试负担加重.
,使得类的扩展性受限.
Java中的空接口