【问题标题】:How can I manually create my own object during deserialization?如何在反序列化期间手动创建自己的对象?
【发布时间】:2015-11-08 22:45:42
【问题描述】:

Serializable 的默认行为以独立于构造函数的特殊方式创建对象。 Serializable 将默认使用反射来读取和写入所有非瞬态非静态字段。

另一方面,Externalizable 不使用反射,因此速度更快,但需要您自己做事:这就是我想要的。

在反序列化期间将使用 Class.newInstance()。这意味着 Externalizable 类必须有一个公共的无参数构造函数。

在非静态最终字段的情况下,公共无参数构造函数是不可接受的,有时甚至是不可能的。

经过一番挖掘,我发现了 android.os.Parcelable,它允许我自己创建对象。还有 com.hazelcast.nio.serialization.IdentifiedDataSerializable 但我必须创建一个工厂类并注册它,与 Parcelable 相比,它看起来像是很多不必要的工作。

我的代码不是 android,目前没有使用任何库。所以我有两个问题:

  1. 是否可以在非安卓 Java 代码中使用 Parcelable?
  2. 允许我在反序列化期间创建和返回自己的对象的最简单方法/影响最小的库是什么?图书馆也不能花钱。

是的,我知道序列化代理,但这不是问题的重点。

【问题讨论】:

  • kryo 可能吗?我仍然想知道我的选择。
  • 那么问题的真正意义是什么?序列化似乎完全符合要求。显然 (1) 的答案是否定的,因为 Parcelable 不是 Java 的一部分。
  • 我想要比 Externalizable 更多的控制权。我希望能够从流中读取数据并决定调用构造函数或工厂或重用已经存在的对象等。我知道有 readResolve 但我试图避免出于不同的原因使用它。
  • 在实现Serializable 的类上使用readObjectwriteObject 怎么样?通过这种方式,您可以控制如何序列化/反序列化对象。
  • Parcelable 反序列化调用流中传递的自定义静态方法。然后该方法决定如何以及是否创建对象。另一方面,Serializable/Externalizable 创建对象,然后将流传递给非静态方法,然后使用可能丢弃创建的对象的 readResolve。我希望有一个相当于 Parcelable 的东西。如果无法合理地做到这一点,那么我将坚持使用带有读/写对象的可序列化。这主要是偏好(少创建一个对象并不重要)。

标签: java deserialization


【解决方案1】:

一个(当然是部分的)解决方案是仅在您尝试序列化的任何对象树的“根”类上使用 Externalizable。它包含的任何字段(包括对象引用的深层副本)都可以通过将 ObjectInput 传递给您的工厂方法(或传递给采用 ObjectInput 的构造函数)来序列化。这允许除根对象之外的所有对象都是不可变的等。

当然,如果对象树的根对象是不能有无参数构造函数的对象,这将无济于事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多