2016-06-30 83 views
-2

我正在研究Java中的序列化函數,該函數理想情況下應採用任何實現接口(類似於Serializable)的類。作爲其中的一部分,我想跟蹤對自動實現序列化接口的對象的更改。爲了做到這一點,我試圖從持久性和內存中讀取最後寫入的對象的副本,只要修改版本一樣長。然而,我很難找出一個適當的方法來在兩個(原始的和改變的)對象之間引用一個不會消耗大量內存的方法。到目前爲止,我已經考慮了幾個方法可以做到這一點,所有的問題:使用副本跟蹤任何Java對象的更改

  1. 成員添加到所改變對象的類/超它引用原始版本的克隆,這樣,每次改變對象寫入,作者可以訪問原文並計算差異。但是,這需要使用繼承來正確完成,這對於這一點來說是不好的形式,特別是考慮到Java只允許一個超類(當我們想要對一個擴展其他東西的對象執行序列化時會發生什麼?另外,它不一定會使語義意義上,所討論的對象「是」一種可以序列化的東西)。這不能通過接口來實現(接口當然不允許聲明變量)。
  2. 有某種鏈接數據結構 - 可能是某個靜態地圖。這會失敗,因爲鏈接結構將始終引用已更改的對象,從而防止在垃圾收集中釋放它,即使代碼的操作部分早已解除引用該對象時也是如此。也許有一些方法可以使垃圾收集器沒有查看的引用 - 也許使用Java哈希?
  3. 以某種方式將克隆的原始文件作爲動態成員(可能是私人/隱藏的)添加到已更改的副本中,也許是用反射。這看起來像是非常糟糕的形式,但是隻會從更改後的版本向原始克隆添加引用,這意味着將不存在GC問題(原始克隆沒有除修改版本之外的任何引用),前提是GC將檢測到從原來的改變的參考。

是否還有其他明顯的東西我在這裏失蹤?任何方式使上述解決方案工作?

回答

1

由於似乎沒有更好的方法,我將編寫一些自動擴展要被序列化的對象的類的代碼。新的子類將克隆作爲成員,但除了序列化代碼外,它們將被視爲超類。我看到的唯一衝突來自Object.getClassName()和它的相關功能(instanceof)。也許我可以想出一種方法來覆蓋getClassName方法。我希望有一種更簡單的方法來獲得這種透明度。