2016-11-29 2 views
0

Haftungsausschluss - Dies ist ein Teil eines Schulsemesterprojekts.Memento-Muster in Java - Serialisierung der inneren Klasse

Wir sollten Memento-Muster verwenden, um einen Objektstatus zu speichern. Dieses Objekt ist ein Modell in MVC. So wie ich es jetzt haben, ist (vereinfacht):

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 
    } 
} 

Ich habe gelesen, dass eine Serializable innere Klasse, die während der äußere Klasse ist nicht nicht wirklich möglich in Java für einen vernünftigen Gründen. ABER, in meinem Fall brauche ich nicht, dass die äußere Klasse instanziiert wird, wenn die innere Klasse ist. Innerlich braucht es überhaupt kein Äußeres. Es ist nur so strukturiert, dass die äußere Klasse auf die Mitglieder des Inneren zugreifen kann. Diese

ist, was ist meine natürlich Memento Beschreibung sagt:

enter image description here

... und das macht auch Sinn. Nur das Modell sollte auf die Details in Memento zugreifen können. Das "Caretaker" -Objekt (ein Objekt, das das Speichern/Abrufen der Daten von/zur Platte behandelt) sollte nicht innerhalb des Objekts sichtbar sein. Da Java keine Freundesklassen hat, sollte dies der richtige Weg sein.

Bedeutet es, dass ich Serialisierung nicht verwenden kann, um es wie vorgeschlagen zu implementieren?

Edit:

Ich machte Memento Klasse statisch, sowie Statistik-Klasse, aber ich bin immer noch den Fehler. Es scheint, dass es noch eine ist this Referenz in 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

Ihre Klasse 'Model' oder ihre innere Klasse' Stats' hat Member oder (anonyme) innere Klassen, die Verweise auf Objekte enthalten, die nicht serialisierbar sind. – Jesper

Antwort

0

Eine Instanz einer nicht-statischen inneren Klasse ein versteckter Verweis auf eine Instanz seiner äußeren Klasse hat. Das heißt, wenn Sie die Instanz der inneren Klasse serialisieren, wird die Instanz der äußeren Klasse mit ihr serialisiert. Wenn die äußere Klasse nicht serialisierbar ist, erhalten Sie eine java.io.NotSerializableException.

Wenn Sie nicht über die Instanz der äußeren Klasse wollen mit der Instanz der inneren Klasse serialisiert entlang werden, machen dann die innere Klasse static:

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

A static innere Klasse nicht ein Verweis auf eine Instanz seiner äußeren Klasse.

+0

(..wenn ich in der Mitte war, einen Kommentar zu schreiben ..) Der Begriff statisch verwechselte mich und es war nicht bis jetzt, dass ich tatsächlich nachgeschaut habe, was "verschachtelte statische Klasse" bedeutet. Stellt sich heraus, es ist nicht statisch im Sinne eines "statischen Mitglied", "statische Methode" oder sogar C# -artige statische Klasse. Ich bekomme jedoch immer noch eine NotSerializableException. Sehen Sie sich die bearbeitete Frage bitte an. –

+0

Serialisierbarkeit ist "ansteckend". Die Typen aller Elementvariablen von 'Memento' müssen ebenfalls serialisierbar sein. Zum Beispiel muss 'ModelData' auch serialisierbar sein, und alle Typen, auf die' ModelData' verweist, müssen auch so sein, etc. – Jesper

+0

Oft ist es besser, die Java-Serialisierung nicht zu verwenden, sondern einen anderen Mechanismus zum Speichern des Objektstatus zu verwenden basierend auf einem bekannten Standardformat wie JSON oder XML. Die Java-Serialisierung verwendet ein schwer zu verstehendes Binärformat und ist sehr eng an den Quellcode gebunden (fügen Sie eine Membervariable hinzu, und Sie können alte serialisierte Objekte nicht mehr lesen). – Jesper

Verwandte Themen