【问题标题】:In java, is it possible to add the Serializable interface to class that doesn't have it at runtime?在java中,是否可以将Serializable接口添加到运行时没有它的类?
【发布时间】:2010-01-22 00:34:08
【问题描述】:

有一个类我要序列化,它实现了Serializable,但是它包含的一个对象没有实现Serializable。

有没有办法在运行时修改类以使其实现 Serializable 接口,以便我可以序列化它?我无法在编译时更改它,因为它是第三方库。

也许我必须使用某种字节码编写器之类的东西?

编辑:包含类和包含类都在 3rd 方库中,所以我认为我不能将某些东西标记为瞬态。包含类 被标记为可序列化,但它包含一个不可序列化的对象。

我可以为该类编写自定义序列化方法,但不知道该怎么做,是否必须使用反射来获取私有变量的值?

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    阅读 Serializable 的 javadoc,我明白了:

    需要特殊处理的类 在序列化和 反序列化过程必须实现 这些精确的特殊方法 签名:

    private void writeObject(java.io.ObjectOutputStream out)
         throws IOException
     private void readObject(java.io.ObjectInputStream in)
         throws IOException, ClassNotFoundException;
     private void readObjectNoData() 
         throws ObjectStreamException;
    

    您可以使用它来手动序列化不合作的字段。您可以考虑使用 ASM,但似乎很难相信它是一个可维护的解决方案。

    【讨论】:

    【解决方案2】:

    可以使用transient 修饰符跳过字段。通过提供readObjectwriteObject 方法,可以将其他数据添加到流中。可以对类进行子类化以使其可序列化(尽管您需要管理超类数据),或使用串行代理(请参阅有效 Java)。

    【讨论】:

      【解决方案3】:

      首先,您真的需要这样做吗?也许第三方库中的类在设计上是不可序列化的。即使这只是一个遗漏而不是一个深思熟虑的决定,在帮助类中编写自定义序列化方法也很容易。如果你不得不这样做(就像我不得不这样做,类似的事情)。看看Javassist。你可以这样做:

      ClassPool pool = ClassPool.getDefault();
      CtClass cc = pool.get("mypackage.MyClass");
      cc.addInterface(pool.get("java.io.Serializable"))
      

      编辑:您可以使用像 XStream 这样的第三方序列化 API,而不是自己做所有的脏活。

      【讨论】:

      • 关于在帮助类中编写自定义序列化方法:我该怎么做?我需要使用反射来获取私有变量值吗?
      • 哈哈。在提出问题 32 分钟后,这个答案已经第三个谷歌结果“序列化 java 第三方”。
      【解决方案4】:

      如果一个类没有被标记为 Serializable 这可能是有充分理由的(以数据库连接为例)。因此,首先要明确自己是否真的需要序列化该对象。如果您只需要序列化周围的对象,您可以考虑将包含的对象标记为瞬态。

      【讨论】:

        【解决方案5】:

        您可以使用 java.lang.reflect.Proxy 将 Serializable 接口添加到您没有生命周期控制(即不能对它们进行子类化)的对象实例中,并以这种方式将它们序列化。但是如果没有其他技巧(即引入代理类),您仍然无法将它们读回。

        我建议寻找一般 Java 可序列化机制的替代方案。它在几个方面被设计破坏了。

        【讨论】:

        • 奇怪的是,这么多开发人员对 Java 的“设计中断”序列化完全没问题。滚动你自己的序列化是一个可怕的解决方案 - 这么多标准 Java 库/框架都使用 Serializable - 你应该为每一个都编写一个解决方法吗?
        猜你喜欢
        • 2014-07-09
        • 2018-07-29
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 2011-03-24
        • 2015-09-21
        • 2010-12-22
        • 1970-01-01
        相关资源
        最近更新 更多