-1

I have an Object gameControl, which I'd like to recall when a Method reset is called and just re-create the Object, because there are a lot of references created in the gameControl Object to other classes.

What I've already tried to do is as following:

public void reset() {
  gameControl = null;
  gameControl = new GameControl();
}

and

public void reset() {
  gameControl = new GameControl();
}

and

public void reset() {
  gameControl = null;
  System.gc();
  gameControl = new GameControl();
}

reset is a function in Commands, Commands is called in Main and the object of GameControl is being created in Main().

Note that reset gets the GameControl object by reference.

Reset function is in an enumerator, so Syntax might be a little weird

RESET("reset") {
    public void execute(MatchResult matcher, GameControl gameControl)
            throws ArgException{
        gameControl = null;
        gameControl = new GameControl();
    }

Expected result is when the new Object is created:

Object and Object reference values should be cleared.

Actual result:

Not sure if its the same object, but the reference values are still saved, so I think it is. For instance Two-Dimensional array is being created in gameControl and after the recreation, the object still exists with modified values.

Thanks in advance!

DaiSuki53
  • 15
  • 2
  • 9
  • If you can retrieve somehow a strong reference to an object, this object will not be removed and references won't be cleared. (See `SoftReference` or `WeakReference` for ways to achieve that). – Michael Butscher Feb 09 '19 at 02:14
  • 2
    Not sure it's considered a dupe, but see (https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value)[here]. Long story short, you can't reassign a parameter to change what objects other references are looking at. If you want a reference to point to the new object, you need to explicitly assign it using `=`. It would be easier to do something like wrap the GameControl in a mutable object, and reassign the GameControl inside the wrapper. – Carcigenicate Feb 09 '19 at 02:14
  • What do you mean by “enumerator”? Do you mean a class defined as an `enum`? – Basil Bourque Feb 09 '19 at 02:16
  • no, the class just has an enumerator with overriden execute function from an abstract function which reads commands from the terminal and executes them. – DaiSuki53 Feb 09 '19 at 02:36
  • Please, do not call `System.gc()`. White there are cases, when it makes sense, they're very rare and far away from your use case. Especially, it may improve or worsen performance (with the latter being much more probable), but it can't change the program semantics in the sense you expect. – maaartinus Feb 10 '19 at 19:39

2 Answers2

0

Java is pass-by-value. Only thing is that, when the value is passed to a method, object reference is passed as a value. So changing the reference doesn't impact the references outside of the method. But since you have the reference to the object it is possible to modify object's state with in the method. Simple example to illustrate the same. Detailed discussion on the same here.

public class GameControl {

    private int x,y;

    public GameControl(int x, int y) {
        this.x = x;
        this.y = y;
    }

    private static void reset(GameControl gc) {
        gc = new GameControl(0,0);
    }

    private static void resetTheOtherWay(GameControl gc) {
        gc.x = 0;
        gc.y = 0;
    }

    @Override
    public String toString() {
        return "GameControl [x=" + x + ", y=" + y + "]";
    }

    public static void main(String[] args) {
        GameControl gc1 = new GameControl(10,20);
        System.out.println(gc1);
        reset(gc1);
        System.out.println(gc1);
        resetTheOtherWay(gc1);
        System.out.println(gc1);
    }
}
vmaroli
  • 613
  • 9
  • 21
0
gameControl = null;
gameControl = new GameControl();

No need to assign null explicitly before assigning a new object.

System.gc();
gameControl = new GameControl();

No seed to call for a garbage-collector, for two reasons.

First of all, this call is merely a request to the garbage-collector to run, not an order. The garbage-collector may or may decide to run, and may or may not complete its work right away (may be interrupted or rescheduled depending on the implementation details of a particular garbage collector).

Secondly, garbage collection does not affect the reassignment of your gameControl variable that formerly pointed to object A now pointing to object B. The reassignment happens immediately. If no other object points to A, then A becomes a candidate for garbage-collection. So you do not really care if A is collected (meaning cleared from memory) now or later; your app no longer knows about the existence of A.

Example app

Here is an example app. For your convenience, you can cut-and-paste the entire example thing into a single .java file and execute. In a real app I would use two separate .java files, one per class.

Note that our example here instantiates a new GameControl object three times. Each new GameControl assigns itself a new UUID as an identifier. That proves you are getting a fresh new GameControl each time.

Example app

package work.basil.example;

import java.time.Instant;
import java.util.UUID;

/* Name of the class has to be "Main" only if the class is public. */
class ResetExample {
    public GameControl gameControl;

    // The `main` method.
    public static void main ( String[] args ) {
        System.out.println( "The main method running at " + Instant.now() );

        ResetExample app = new ResetExample();      // Get the app going.

        app.gameControl = new GameControl();        // Populate the `gameControl` member field for the first time.
        System.out.println( "Current GameControl `id`: " + app.gameControl.id );

        app.reset();                                // `reset` method replaces the `gameControl` member field’s current object with a new freshly instantiated `GameControl` object.
        System.out.println( "Current GameControl `id`: " + app.gameControl.id );

        app.reset();
        System.out.println( "Current GameControl `id`: " + app.gameControl.id );
    }

    public void reset () {
        System.out.println( "The `reset` method is running at: " + Instant.now() );
        this.gameControl = new GameControl();
    }

}

class GameControl {
    // Member fields
    public UUID id;

    // Constructor
    public GameControl () {
        System.out.println( "The constructor of `GameControl` is running at: " + Instant.now() );
        this.id = UUID.randomUUID();
    }
}

When run.

The main method running at 2019-02-09T02:33:16.233414Z

The constructor of GameControl is running at: 2019-02-09T02:33:16.265839Z

Current GameControl id: 4ee963c6-a895-4fe8-8463-b890777ad8f4

The reset method is running at: 2019-02-09T02:33:16.280516Z

The constructor of GameControl is running at: 2019-02-09T02:33:16.280796Z

Current GameControl id: b74d9924-8f96-4321-9eca-a104642fc3f8

The reset method is running at: 2019-02-09T02:33:16.281139Z

The constructor of GameControl is running at: 2019-02-09T02:33:16.281213Z

Current GameControl id: 3d8223c6-f93f-4708-832d-6cf60154befa

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154