来自SE_BAD_FIELD
的描述:
可序列化类中的非瞬态非序列化实例字段
此Serializable类定义非原始实例字段,该字段既不是瞬态,也不是序列化,也不是java.lang.Object,并且似乎不实现Externalizable接口或readObject()和writeObject()方法。如果在此字段中存储非Serializable对象,则不会正确反序列化此类的对象。
为什么java.lang.Object
是规则的例外?
答案 0 :(得分:2)
假阳性的数量可能很高,如
public void writeIt(Object o, ObjectOutputStream oos) {
oos.writeObject(o);
}
可能非常好,因为调用者总是传入一个可序列化的派生类的实例。
现在问题是,为什么不是上面的方法签名
public void writeIt(Serializable o, ObjectOutputStream oos) {
oos.writeObject(o);
}
答案是,作为第一个参数传入的接口定义的所有类型的对象都将无法编译。
,例如
Map m = .....
writeIt(m, oos);
所以捕获序列化java.lang.Object(这可能是极为罕见的事件)的价值不值得误报。
答案 1 :(得分:1)
因为所有东西都可以反序列化为java.lang.Object,因为java中的每个类都扩展了java.lang.Object。如果您设法序列化具有非序列化字段的对象,则无法在反序列化中知道该字段的类。因为每个类都是一个对象,所以你总是可以回退到Object类。
class NonSerializableUser {}
class SerializableUser implements Serializable{}
class SomeObject implements Serializable{
public NonSerializableUser nonUser;
public SerializableUser user;
public Object nonUserObj;
public SomeObject(SerializableUser u, NonSerializableUser uu, NonSerializableUser uuu){
user = u;
nonUser = uu;
nonUserObj = uuu;
}
}
在此示例中,反序列化此类将导致nonUser为null,user为正确的SerializableUser类实例,而nonUserObj将为非null,但是它将丢失所有NonSerializableClass方法和字段,它们将不会被序列化。该序列化实例的唯一部分是属于Object的方法和字段。
值得注意的是,许多序列化库(例如ObjectOutputStream)会抱怨非序列化类,并且不会首先序列化此对象。这就是为什么我遗漏了序列化/反序列化步骤的细节。然而,许多xml框架仍将序列化这些类,这往往是这个错误让它成为头脑的情况。