Theodor
Theodor

Reputation: 5676

Whats the correct way to do this variable overwriting?

When overwriting an existing variable, someThing of type Thing below in a method, what is the correct way to do this?

doSomething(someThing);

void doSomething(Thing thing){
    //...
    thing = new Thing(...); // receives warning in Eclipse
}

or

someThing = doSomething(someThing);

Thing doSomething(Thing thing){
    //...
    return new Thing(...);
}

Upvotes: 1

Views: 72

Answers (1)

Mat
Mat

Reputation: 206909

Your first sample doesn't change the variable someThing in the caller. The assignment is only visible in the doSomething method.

The second sample does change someThing in the caller.

So if you want to change someThing in the caller, option 2 is viable, while option 1 is not.

See Is Java "pass-by-reference" or "pass-by-value"? for why this works that way.

Assuming the following code, and a Thing that has a print method and a String member.

void foo() {
  Thing one = new Thing("hello");  // 1
  bar(one);
  one.print();                   // 5
}

void bar(Thing two) {            // 2
  two = new Thing("bye");        // 3
}                                // 4

The assignment at point 1 first creates a new Thing object:

                       Thing{data="hello"}

Then stores a reference to that in one:

one *----- refs --------v
                       Thing{data="hello"}

When you enter bar at point 2, a new reference to the same object is created:

one *----- refs --------v
                       Thing{data="hello"}
two *----- refs --------^

Then line 3 does the same thing as line 1, i.e. create a new Thing object:

one *----- refs --------v
                       Thing{data="hello"}
two *----- refs --------^

                       Thing{data="bye"}

then stores a reference to that new object in two:

one *----- refs --------v
                       Thing{data="hello"}

two *----- refs --------v
                       Thing{data="bye"}

Notice that only two is modified. The assignment changes what two refers to.

When you return from bar, at line 4, two goes out of scope, the "bye" Thing no longer has anything referencing it (and will eventually be garbage collected).

one *----- refs --------v
                       Thing{data="hello"}

                       Thing{data="bye"} // dead, will be collected

So at point 5, as you can see, hello will be printed - nothing ever changed the object that one refers to.

Upvotes: 2

Related Questions