views:

24

answers:

4

I have a problem with the reference of a variable when loading a saved serialized object from a data file. All the variables referencing to the same object doesn't seem to update on the change. I've made a code snipped below that illustrates the problem.

    Tournament test1 = new Tournament();
    Tournament test2 = test1;

    try {
        FileInputStream fis = new FileInputStream("test.out");
        ObjectInputStream in = new ObjectInputStream(fis);

        test1 = (Tournament) in.readObject();

        in.close();

    }
    catch (IOException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }
    catch (ClassNotFoundException ex){
        Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
    }

    System.out.println("test1: " + test1);
    System.out.println("test2: " + test2);

After this code is ran test1 and test2 doesn't reference to the same object anymore. To my knowledge they should do that since in the declaration of test2 makes it a reference to test1. When test1 is updated test2 should reflect the change and return the new object when called in the code. Am I missing something essential here or have I been misstaught about how the variable references in Java works?

A: 

When you unmarshal an object with serialization and assign it to a variable you replace the old reference (in your case a new Tournament()) with the new object.. so test2 will be pointing to the original Tournament while test1 will reference to the just unserialized object..

It's like doing:

Tournament t1 = new Tournament();
Tournament t2 = t1;

t1 = new Tournament();

will t1 == t2? Of course not..

Jack
+3  A: 

Am I missing something essential here or have I been misstaught about how the variable references in Java works?

Most likely you misunderstood what you were taught, or were taught something wrong. All variables of reference type (i.e. not primitive types) refer directly to an object.

Tournament test1 = new Tournament();

Creates a new instance of Tournament and makes test1 refer to it.

Tournament test2 = test1;

Copies the reference from test1 to test2, making them both refer to the same object.

test1 = (Tournament) in.readObject();

Makes test1 refer to a different object that has been deserialized from the stream, while test2 still refers to the original object.

Michael Borgwardt
Alright, thanks for clearing that out. I have always thought that Tournament test2 = test1; would make test2 "always refer to whatever test1 refers to". Since that's that's not the case, is there any way to do such a thing in Java?
Snail
@Snail: on the level of variable names, no. Instead, you use mutable objects that you modify rather than reassign.
Michael Borgwardt
A: 

The problem is the notion that Java passes and assigns by reference. It doesn't. Java passes and assigns by value. It just happens that with reference types, the value passed is a reference.

The difference is this: Say you have some test code

Tournament test1 = new Tournament();
Tournament test2 = test1;

test1 = new Tournament();
System.out.println(test1 == test2 ? "Equal" : "Not Equal");

If Java passed by reference, it would print Equal, because test2 would just be an alias for test1. However, because Java passes by value, it prints Not Equal.

R. Bemrose
There isn't any passing happening at all in that code. "Pass by value" and "pass by reference" is only relevant to method parameters.
Michael Borgwardt
A: 

You're not "updating" test1 anywhere.

This line is assigning a different object of type Tournament that it's reading from the input stream, and assigning this new object to test1:

test1 = (Tournament) in.readObject();

Meanwhile, test2 is still pointing to the original object that was allocated at the start of your code block.

Skrud