Java:不变性和序列化

Java:不变性和序列化,java,serialization,immutability,Java,Serialization,Immutability,当我有一个不可变的父类A不是final,而另一个类B扩展了它(B是可变的)时,有没有可能因为序列化而影响A的不可变性 我写了一个小程序来序列化一个对象,改变了它在程序中的状态,然后反序列化它。我以序列化对象的形式将其恢复。所以我想知道有没有办法通过序列化来改变A的不变性?你不能改变它的不变性(类仍然是不可变的),但是你可以通过编辑序列化的信息来改变它的值 您也可以通过反射来改变它,immutable不是某种魔法保护,它只是创建了一个没有变种的类来帮助整个程序的稳定性。虽然变量可能是最终的,但这甚

当我有一个不可变的父类A不是final,而另一个类B扩展了它(B是可变的)时,有没有可能因为序列化而影响A的不可变性


我写了一个小程序来序列化一个对象,改变了它在程序中的状态,然后反序列化它。我以序列化对象的形式将其恢复。所以我想知道有没有办法通过序列化来改变A的不变性?

你不能改变它的不变性(类仍然是不可变的),但是你可以通过编辑序列化的信息来改变它的值

您也可以通过反射来改变它,immutable不是某种魔法保护,它只是创建了一个没有变种的类来帮助整个程序的稳定性。虽然变量可能是最终的,但这甚至不是必需的——要保持不变,您只需始终为所有方法返回相同的值


无论如何,如果你要扩展一个不可变的类,你可能也希望你的扩展是不可变的——如果你不是真的不想扩展这个类,也许你只是想封装它(是否存在一个is-a关系或has-a?

这完全取决于你的要求。如果您只是想得到一个不同于输入值的值,那么可以通过序列化来实现。序列化数据与内存中存在的
A
实例完全分离。当Java从序列化数据重建对象时,它不知道或不关心用于创建该数据的
A
的原始实例。它只是基于序列化信息中提供的蓝图在内存中构建一个数据结构

因此,如果要修改重构
A
时返回的内容,可以通过手动修改二进制序列化数据来实现。这样做需要对Java的序列化格式有很好的理解,但肯定可以做到

虽然如果您询问是否有任何方法可以通过序列化修改
A
的原始实例(例如,以某种方式使同一对象的值发生变化,而不通过反序列化构建新实例),但答案是否定的,您不能。序列化只是创建对象当前状态的快照。反序列化将创建一个与源实例完全分离的新对象实例。因此,尽管您可以手动更改该值,但具有新值的新对象在反序列化后仍然是不可变的


如果您询问是否有方法序列化不可变类
a
的实例,然后将数据反序列化为标识为类
a
实例但碰巧是可变的,则答案也是否定的。序列化数据指定要表示的对象类,但是类定义本身并没有序列化。因此,您可以更改指定的类,以便序列化
A
的实例,然后反序列化可变类
B
的实例,但这与返回
A
的可变实例不同

序列化对象时,该对象不会更改是否不可变

反序列化新对象时,它是根据记录的信息和反序列化的方式重建第一个对象

例如,如果您有一个不可变的类,并且一个字段是瞬态的,则反序列化副本将不会设置该字段(您将其设置为瞬态)