當我有一個不變的父類是不是終點,而另一個類B擴展它(B是可變的),是否有任何方式的不變性可以因爲系列化的影響?的Java:不變性和系列化
我寫了一個小程序序列化對象,在程序中改變其狀態,然後反序列化它。我將對象以序列化的形式返回。所以我想知道是否有任何方法可以通過序列化來改變A的不變性?
當我有一個不變的父類是不是終點,而另一個類B擴展它(B是可變的),是否有任何方式的不變性可以因爲系列化的影響?的Java:不變性和系列化
我寫了一個小程序序列化對象,在程序中改變其狀態,然後反序列化它。我將對象以序列化的形式返回。所以我想知道是否有任何方法可以通過序列化來改變A的不變性?
這取決於你正在問什麼。如果您只想獲得與您投入的價值不同的價值,那麼是的,您可以通過序列化來實現。序列化數據完全脫離內存中存在的A
實例。當Java從序列化數據重建對象時,它不知道或關心用於創建該數據的原始實例A
。它只是基於序列化信息中提供的藍圖構建內存中的數據結構。
所以,如果你想修改,當你重建A
你得到的是什麼,你可以通過手動修改二進制序列化的數據這樣做。這樣做需要對Java的序列化格式有一個很好的理解,但它當然可以完成。
雖然如果您問是否有任何方法通過序列化來修改A
的原始實例(如以某種方式獲取相同的對象以更改值,而不通過反序列化構建新實例),那麼答案是的,你不能。序列化只是創建對象當前狀態的快照。反序列化會創建一個與源實例完全分離的新對象實例。因此,儘管您可能會手動更改該值,但具有新值的新對象在反序列化後仍然是不可變的。
如果你問是否有辦法序列化不可變類A
的實例,然後將數據反序列化爲標識爲A
類的實例,但碰巧是可變的,那麼答案也是否定的。序列化數據指定正在表示什麼類的對象,但類定義本身不是序列化的。因此,您可以更改指定的類,以便序列化A
的實例,然後反序列化可變類B
的實例,但這與獲取A
的可變實例不同。
你不能改變它的不變性(類仍將是不變的),但你可以通過編輯序列化的信息改變其值。
您也可以通過反射改變它,不可變的不是某種魔法的保護,它只是創造無存取器類,以幫助全部測試程序穩定性。雖然變量可能應該是最終的,但這甚至不是必需的 - 要成爲不可變的,你必須始終爲所有方法返回相同的值。無論如何,如果你打算擴展一個不可變的類,你可能希望你的擴展也是不可變的 - 如果不是,你可能不想擴展這個類,也許你只是想封裝它(有沒有一種關係,或有一個?)
當您序列化一個對象時,該對象不會改變它是否是不可變的。
當你去連載一個新的對象,它是一種基於記錄的信息,以及如何做反序列化的第一個對象的重建。
例如,如果你有一個不可改變的類,並且一個字段是瞬態的,那麼反序列化的副本將不會有該字段集(你使它成爲瞬態的)