2016-11-29 41 views
0

免責聲明 - 這是學校學期項目的一部分。Java中的紀念圖案 - 內部類的序列化

我們應該使用Memento模式來保存對象狀態。該對象是MVC中的一個模型。所以,我有它現在(簡體)的方式:

public class Model { 
    // ... 
    public static class Memento implements Serializable { 
     protected Stats stats; 

     public Memento(Stats stats) { 
      this.stats = stats; 
     } 
    } 

    public static class Stats implements Serializable { 
      protected int score; 
      protected int cannonPos; 
      protected int cannonAngle; 
      protected int cannonSpeed; 
      protected int totalShotsFired = 0; 
      protected int enemiesHit; 
      protected transient List<StatsObserver> observers = new ArrayList<StatsObserver>(); 
      // + getters etc 
    } 
} 

我已閱讀,有一個序列化的內部類,而外部類的是不是是不是真的有可能在Java中的合理理由。但是,在我的情況下,我不需要在內部類實例化外部類時。內在根本不需要外部。它只是這樣構造的,以便外部類可以訪問內部的成員。

這是我課程的備忘錄描述說什麼:

enter image description here

...這是有道理的爲好。只有模型應該能夠訪問Memento內的細節。 「看守」對象(處理在磁盤上保存/檢索數據的對象)不應在對象內部看到。由於Java沒有朋友類,這應該是一條路。

這是否意味着爲了實現它作爲建議我不能使用序列化?

編輯:

我做紀念品類的靜態,以及統計類,但我仍然得到錯誤。看來,還有在Model.Stats

java.io.NotSerializableException: cz.melkamar.adp.shooter.model.Model 
    - field (class "cz.melkamar.adp.shooter.model.Model$Stats", name: "this$0", type: "class cz.melkamar.adp.shooter.model.Model") 
    - object (class "cz.melkamar.adp.shooter.model.Model$Stats", [email protected]) 
    - field (class "cz.melkamar.adp.shooter.model.Model$Memento", name: "stats", type: "class cz.melkamar.adp.shooter.model.Model$Stats") 
    - root object (class "cz.melkamar.adp.shooter.model.Model$Memento", [email protected]) 
+0

您的類「模型」或其內部類「Stats」具有成員或(匿名)內部類,該類持有對不可序列化的對象的引用。 – Jesper

回答

0

一個非靜態內部類的實例this參考具有隱蔽參照其外部類的一個實例。這意味着如果您要序列化內部類的實例,則外部類的實例將與其一起被序列化。如果外部類不是可序列化的,你將得到一個java.io.NotSerializableException

如果不希望外部類的實例以內部類的實例進行序列化一起做,然後進行內部類static

public class Model { 
    // ... 
    public static class Memento implements Serializable { 
     protected ModelData data; 
     // ... 
    } 
} 

一個static內部類沒有引用其外部類的一個實例。

+0

(..因爲我正在寫評論。)靜態這個詞使我困惑,直到現在我才真正看到了「嵌套靜態類」的含義。從靜態成員,靜態方法甚至C#靜態類的意義上來看,它並不是靜態的。不過,我仍然得到一個NotSerializableException。請看看編輯過的問題。 –

+0

可串行性是「傳染性」的。 「Memento」的所有成員變量的類型也必須是可序列化的。例如,'ModelData'也必須是可序列化的,'ModelData'引用的所有類型必須也是如此,等等。 – Jesper

+0

通常最好不使用Java序列化,而是使用不同的機制來存儲對象狀態,最好是基於衆所周知的標準格式,如JSON或XML。 Java序列化使用難以理解的二進制格式,並且非常緊密地綁定到源代碼(添加一個成員變量,並且不能再讀取舊的序列化對象)。 – Jesper