【问题标题】:FindBugs - SE_BAD_FIELD rule, why it ignores java.lang.Object?FindBugs - SE_BAD_FIELD 规则,为什么它忽略 java.lang.Object?
【发布时间】:2011-08-19 11:25:48
【问题描述】:

来自SE_BAD_FIELD的描述:

可序列化类中的非瞬态不可序列化实例字段

这个 Serializable 类定义了一个非原始实例字段,它既不是瞬态的、Serializable 也不是 java.lang.Object,并且似乎没有实现 Externalizable 接口或 readObject() 和 writeObject() 方法。如果此字段中存储了不可序列化的对象,则此类的对象将无法正确反序列化。

为什么java.lang.Object 是规则的例外?

【问题讨论】:

  • 也许作者期望如果你故意选择 java.lang.Object 作为属性的类型(最通用的类​​型,你不能假设任何东西)而不是某些特定类型,你已经很清楚,序列化不能在该领域合理地工作。但我同意这个例外很奇怪:毕竟,错误很可能是你忘记了瞬态修饰符!
  • 可能与锁对象有关。

标签: java serialization findbugs


【解决方案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 框架仍然会序列化这些类,这往往是这个 bug 出现的情况。

【讨论】:

    【解决方案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(这可能是极其罕见的事件)的价值不值得误报影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2020-10-27
      • 1970-01-01
      相关资源
      最近更新 更多