当前位置: 首页 > 知识库问答 >
问题:

停止java继承树中某些类类型的序列化

尉迟国发
2023-03-14

我有一个继承树,其中
A类实现了可序列化{}
B类扩展A{}C类扩展B{}等等,直到Z类扩展Y{}

根据连载:

“由于Class A实现了Serializable,因此Z之前的所有子类都变成了“Serializable”。当我们尝试序列化Z的对象时,所有的超类对象都将被序列化

问题:

当我序列化Z类的对象时,如何避免C类的对象被序列化?

共有1个答案

公羊新
2023-03-14

好的,如果C在Z的超类链中,并且您想要序列化Z,那么C也将被序列化。您可以使用以下技术之一避免或解决此问题:

重新排列类层次结构。

也就是说,使C不再是Z的超类。假定你不想这样做,但是考虑到不序列化C的目标可能是合理的。

控制C中序列化的字段。

可以将未序列化的C字段标记为transient。最好是在C中声明一个serialPersistentFields数组,该数组可能为空,包含要序列化的C字段的名称。这可能比将不希望序列化的字段标记为瞬态字段更容易或更易于维护。请注意,C仍然是序列化的,但可以省略其字段的序列化。

为C提供自定义序列化格式。

也就是说,使用readObjectwriteObject方法。如果不从writeObject方法调用defaultWriteObject,则不会发生C的自动字段序列化。同样,不要在readObject方法中调用defaultReadObject。请注意,如上所述,这仍然会序列化C本身,但避免序列化其部分或全部字段。

为Z提供序列化代理。

为Z提供一个writeReplace方法。writeReplace方法安排事情,以便当有人请求序列化Z时,另一个对象(例如称为ZProxy)被序列化。让您的writeReplace方法构造一个ZProxy实例,该实例正好包含您想要序列化的Z中的数据,并返回该ZProxy实例。该instance将被序列化以代替Z实例。ZProxy不必与Z位于同一个类层次结构中;这可能完全无关。反序列化ZProxy实例时,请确保ZProxy有一个readResolve方法,该方法可以从ZProxy中的数据构造一个Z实例,并返回Z实例。

有关序列化代理的更多信息,请参见Bloch,《有效Java》,第78项。

您可能还希望提供一个引发异常的Z.readObject方法,以防止有人伪造一个声称包含Z的序列化实例的序列化ByTestStream,然后对其进行反序列化。这强制了一个约束,即在序列化字节流中只出现ZProxy实例,而不出现实际的Z实例。

 类似资料:
  • 如何在Gradle中清晰地分离可能需要两个不同配置任务的任务?我试图将要在buildsrc/dbhelpertasks.gradle文件中执行的实际任务与父build.gradle文件分开。build.gradle将包含在dbhelpertasks.gradle中使用的部分配置的任务。 我有许多不同的数据库要连接并在其上执行SQL,因此创建了一个采用数据库名称和URL的SQLServerTask。

  • 我一直在做一个基本的类继承练习,尽管我认为我已经掌握了它的jist,但我的程序并没有按应有的方式工作。我遇到了编译错误,但还没有弄清楚原因——如果你们都能在这里帮助我,那就太好了。 首先,这里有三个文件1。人java——基类2。大学生java——一个派生的Person类。java 3。家庭java——不太确定,我认为它是自己的基类 人java有两个实例变量,String name和int age,

  • 我试图弄清楚Java中的继承和数组,并试图让这些类一起工作。我相信我已经继承下来了,但我仍在为数组部分而挣扎。 有三个文件: 1. Person.java-基类2. Student.java-派生的Person.java3. Family.java-不太确定,我认为这是它自己的基类 人java有两个实例变量,String name和int age,以及各种各样的构造函数toString、equal

  • 我试图写一个类(SalaryEmployee)和子类(ComissionEmployee),但我没有得到正确的工资,我不能做SE1.SetSalesMount(20000)。我哪里出了问题? 这是主要的:

  • 本文向大家介绍JavaScript中的继承之类继承,包括了JavaScript中的继承之类继承的使用技巧和注意事项,需要的朋友参考一下 继承简介       在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。在大多数其他面向对象语言中,继承一个类只需使用一个关键字即可。在JS中想要达到继承公用成员的目的,需要采取一系列措施。JS属于原型式继承,得益于这种灵活性,我们既可以

  • 我在Hibernate中有道传承,下面是代码: 用户DAO: 我有一个域类用户和两个子类用户:Customer和Sales。我有两个dao类,分别用于客户和销售。 用户DAO: 客户道: 销售DAO: 我的问题是,当我使用CusterDap调用方法getUserByUsername()(继承自BaseDaoImpl)与销售的用户名(拥有用户名的用户是SalesRep的实例,而不是客户)时,它会抛出