为了账号安全,请及时绑定邮箱和手机立即绑定

Java自定义序列化

Java自定义序列化

哈士奇WWW 2019-10-19 14:14:06
我有一个对象,其中包含一些要序列化的不可序列化字段。它们来自我无法更改的单独API,因此使它们可序列化不是一种选择。主要问题是Location类。它包含所有我需要的可以序列化的四件事。如何使用read / writeObject创建可以执行以下操作的自定义序列化方法:// writeObject:List<Integer> loc = new ArrayList<Integer>();loc.add(location.x);loc.add(location.y);loc.add(location.z);loc.add(location.uid);// ... serialization code// readObject:List<Integer> loc = deserialize(); // Replace with real deserializationlocation = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));// ... more code我怎样才能做到这一点?
查看完整描述

3 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

类似于@momo的答案,但不使用List和自动装箱的int值,这将使其更加紧凑。


private void writeObject(ObjectOutputStream oos) throws IOException {

    // default serialization 

    oos.defaultWriteObject();

    // write the object

    oos.writeInt(location.x);

    oos.writeInt(location.y);

    oos.writeInt(location.z);

    oos.writeInt(location.uid);

}


private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {

    // default deserialization

    ois.defaultReadObject();

    location = new Location(ois.readInt(), ois.readInt(), ois.readInt(), ois.readInt());

    // ... more code


}


查看完整回答
反对 回复 2019-10-19
?
慕标琳琳

TA贡献1830条经验 获得超9个赞

如果必须是Java序列化,我唯一知道的方法就是重新定义readObject()writeObject(),并且在所有类中都引用实例,Location如Momo的答案所示。请注意,这将不允许您序列化Location[],并要求您对Collection<Location>代码中出现的所有子类进行子类化。此外,它要求将类型的字段Location标记为瞬态,这会将它们的定义排除在写入序列化流之外,从而有可能挫败不兼容类更改的检测。

更好的方法是简单地重写ObjectOutputStream.writeObject。that,那个方法是final。您可以改写ObjectOutputStream.writeObjectOverride(),但是该方法不能委托默认实现,ObjectOutputStream.writeObject0()因为该方法是private。当然,您可以使用反射来调用私有方法,但是...

因此,我建议验证您的约束。一定要Java序列化吗?您真的不能更改类的定义Location吗?

如果您有要分类的源代码Location,则将其添加implements Serializable并将其添加到您的classpath中非常简单。是的,每当升级库时,都必须再次执行此操作,但是它可能比其他方法更好...


查看完整回答
反对 回复 2019-10-19
  • 3 回答
  • 0 关注
  • 344 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信