NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: readResolve() vrací singleton instanci defaultních hodnot

V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
GoliathShouldWin:23.4.2015 21:08

Zdravím,
mám problém se serializací singleton třídy. Dokud nepoužiju readResolve(který je pro zachování singleton funkčnosti nezbytný) vše funguje jak má, ale když je readResolve() součástí kódu, vrací serializace instanci s defaultními hodnotami ne těmi, které byly deserializovány. Zde je kód a předem děkuji za každou radu.

// přetížení readObject
  private void readObject(ObjectInputStream oi) throws IOException, ClassNotFoundException{

    oi.defaultReadObject(); // přečtení netransientnich (initializable) atributu

    this.headColor      = Color.web((String)oi.readUTF()); // inicializování (přečtení a parsnutí serializovatelných hodnot do neserializovatelných atributu) trans. atributu
    this.bodyColor      = Color.web((String)oi.readUTF());
    this.gameBoardColor = Color.web((String)oi.readUTF());
    this.statsBoxColor  = Color.web((String)oi.readUTF());

    switch ((String)oi.readUTF()){ // inicializace atributu typu Speed(enum)

        case "SLOW"  : this.speed = Speed.SLOW;   break;

        case "NORMAL": this.speed = Speed.NORMAL; break;

        case "FAST"  : this.speed = Speed.FAST;   break;

        case "INSANE": this.speed = Speed.INSANE; break;

        default      : this.speed = Speed.NORMAL;

    }
  }


  // pretizeni writeObject
  private void writeObject(ObjectOutputStream oo) throws IOException{
    oo.defaultWriteObject(); // zapsání netransient atributu (Serializovatelné typy)

    oo.writeUTF(this.headColor.toString()); // zapsání hodnot neserializovatelných (transientnich) atributu v serializovatelné podobě (typu)
    oo.writeUTF(this.bodyColor.toString());
    oo.writeUTF(this.gameBoardColor.toString());
    oo.writeUTF(this.statsBoxColor.toString());
    oo.writeUTF(this.speed.name());

  }

  // nefunkční readResolve
  private Object readResolve()throws ObjectStreamException{
      return SnakeGameSettings.getInstance();
  }

  */


  // metoda pro načtení settingu
  public void loadSettings(String storageAddress) throws IOException{
    ObjectInputStream input = null;
    File storageFile = new File(storageAddress);

    try{
     if (storageFile.createNewFile()){
        System.out.println("DEBUG MESSAGE: uložiště settingClass aplikace bylo poprvé vytvořeno");

     }else{
       input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(storageFile)));
       GAME_SETTINGS = (SnakeGameSettings) input.readObject();
       System.out.println("DEBUG MESSAGE: načten uložený setting objekt");
     }

    }catch (Exception loadSettExcp){ System.out.println(loadSettExcp.getMessage());
     }finally{if (input != null){input.close();} }
  }


 // metoda pro uložení setting
  public void storeSettings(String storageAddress) throws IOException{
   ObjectOutputStream output = null;

    try{
      output = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(storageAddress)));
      output.writeObject(GAME_SETTINGS);

    }catch (IOException storeSettExcp){ System.out.println(storeSettExcp.getMessage());
     }finally{if (output != null){output.close();}
     }
  }
public class SnakeGameSettings implements Serializable {
// trida vyuziva konceptu staticke singleton instance
  public enum Speed{ SLOW(1), NORMAL(3), FAST(5), INSANE(7); // enum trida pro rychlosti
    public int movementSpeed;

    private Speed(int speed){ // privatni konstruktor
     this.movementSpeed = speed;
    }
  }

  // singleton instance této třídy
  private static SnakeGameSettings GAME_SETTINGS;

  // atributy
 transient private Color headColor;
 transient private Color bodyColor;
 transient private Color gameBoardColor;
 transient private Color statsBoxColor;
           private int   xBorders;
           private int   yBorders;
 transient private Speed speed;

 private static final long serialVersionUID = 6661666166616661L; // serializační ID

 // privátní kontruktor (nevolatelný zvenčí)
  private SnakeGameSettings(){

   this.headColor      = Color.BLACK;
   this.bodyColor      = Color.RED;
   this.gameBoardColor = Color.WHITE;
   this.statsBoxColor  = Color.web("#f7ab74");
   this.xBorders       = 600;
   this.yBorders       = 600;
   this.speed          = Speed.NORMAL;

  }

 // metoda pro vrácení/vytvoření jedinné singleton instance
  public static SnakeGameSettings getInstance(){
    if (GAME_SETTINGS == null){
        GAME_SETTINGS = new SnakeGameSettings();
       }

        return GAME_SETTINGS;
  }
 
Odpovědět
23.4.2015 21:08
Avatar
GoliathShouldWin:24.4.2015 13:28

Ok, vyřešeno.

private Object readResolve()throws ObjectStreamException{
    GAME_SETTINGS = this;
    return null;
  }

  // metoda pro načtení settingu
  public void loadSettings(String storageAddress) throws IOException{
    ObjectInputStream input = null;
    File storageFile = new File(storageAddress);

    try{
     if (storageFile.createNewFile()){
        System.out.println("DEBUG MESSAGE: uložiště settingClass aplikace bylo poprvé vytvořeno");

     }else{
       input = new ObjectInputStream(new BufferedInputStream(new FileInputStream(storageFile)));
       input.readObject();

       System.out.println("DEBUG MESSAGE: načten uložený setting objekt");
     }

    }catch (Exception loadSettExcp){ System.out.println(loadSettExcp.getMessage());
     }finally{if (input != null){input.close();} }
  }
Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět
24.4.2015 13:28
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.