Search code examples
javaserializationreferencecopyclone

Can't give values properly trougth serialization


It is going to be a very basic question I suppose, but I've been searching for the answer fo hours and I just can't figure out where's my code go wrong. So: I do serialze an object called SerializableObject, than read it back. In the deserializing method I get a temporary object, which I want to copy to an other new SerializeableObject, wich I want to use after, but I can't copy it properly, however the temporary object got the values properly, at the deserialization. Here's my classes: SeralizeableObject:

public class SerializableObject implements Serializable, Cloneable{

private Vector<int[]> mixMade;
private Vector<int[]> stepsMade;
private long time;
private int steps;
private int winnerState;

public SerializableObject(Vector<int[]> mixMade, Vector<int[]> stepsMade,
 long time, int steps, int winnerState) {
    this.mixMade = mixMade;
    this.stepsMade = stepsMade;
    this.time = time;
    this.steps = steps;
    this.winnerState = winnerState;
}

@Override
public String toString() {
    String str = "";
    for(int[] mixEl : mixMade){
        str += mixEl[0] + ", " + mixEl[1] + "|";
    }
    str += " mixes\n";
    for(int[] stepEl : stepsMade){
        str += stepEl[0] + ", " + stepEl[1] + "|";
    }
    str += " steps\n";
    str += "time: " + time + ", stepsnum: " + steps + ", 
winstate: " + winnerState;
    return str;
}    

@Override
public SerializableObject clone() {
    SerializableObject serObj;
    Vector<int[]> mixMadeTemp   = new Vector<int[]>();
    Vector<int[]> stepsMadeTemp   = new Vector<int[]>();
    for(int i = 0; i < mixMade.size(); ++i){
        mixMadeTemp.add(mixMade.get(i));
    }
    for(int i = 0; i < stepsMade.size(); ++i){
        stepsMadeTemp.add(stepsMade.get(i));
    }
    serObj = new SerializableObject(mixMadeTemp, stepsMadeTemp, 
time, steps, winnerstate);
    return serObj;
}

}

The Serializator:

public class ObjectSerializator {

public ObjectSerializator() {

}

public void toFile(String filepath, SerializableObject serObj){
    ObjectOutputStream out;
    try{
        FileOutputStream fileOut = new FileOutputStream(filepath);
        out = new ObjectOutputStream(fileOut);
        out.writeObject(serObj);
    }catch (IOException ex) {

    }    
}

public void fromFile(String filepath, SerializableObject serObj){
    SerializableObject tempSerObj;
    try {
        FileInputStream fileIn = new FileInputStream(filepath);
        ObjectInputStream in = new ObjectInputStream(fileIn);

        tempSerObj = (SerializableObject) in.readObject();
        System.out.println(tempSerObj + "TEMP");
        serObj = tempSerObj.clone();

        in.close();
        fileIn.close();
    } catch (IOException ex) {

    } catch (ClassNotFoundException ex) {

    }
}

}

note: the serobj reference points properly to the good values, inside the fromFile method A filechooser class, where the user can chhose the file to load from:

public class FileChooser extends JFileChooser{

private ObjectSerializator serializator;

public FileChooser() {
    serializator = new ObjectSerializator();
}

public void load(SerializableObject serObj){
        int retValue = showOpenDialog(null);
        serializator.fromFile(getSelectedFile().getAbsolutePath(), serObj);
}}

than in my mainfram I call it from a buttonaction

public void load(){
    SerializableObject serObj = new SerializableObject(new Vector<int[]>(), new 
Vector<int[]>(), 10, 10, 200);
    fileChooser.load(serObj);
    System.out.println(serObj + " LAST");
}

Here's my output:

3, 2|4, 3| mixes

0, 0|0, 1|0, 0| steps

time: 6000, stepsnum: 3, winstate: 0TEMP

-------------------

 mixes

 steps

time: 10, stepsnum: 10, winstate: 200 LAST

Solution

  • The object you've deserialized gets lost.

    In your fromFile method, you have the following line:

    serObj = tempSerObj.clone();
    

    But serObj is an argument to the method. The line above changes the local serObj variable, whereas the original object remains intact. The calling method (load) still holds a reference to the old (original) object.

    Your fromFile method shouldn't accept a SerializableObject as an argument; rather, it should return one. Then the FileChooser.load method should return it as well. Finally, the load method of the main frame should look something like:

    public void load() {
        SerializableObject originalObject = new SerializableObject(new Vector<int[]>(), new Vector<int[]>(), 10, 10, 200);
        // Here you can do something with the newly created object, such as save it to a file.
    
        SerializableObject deserializedObject = fileChooser.load();
        System.out.println(deserializedObject + " LAST");
    }