对象不会被新对象替换

时间:2019-02-09 02:07:01

标签: java garbage-collection

我有一个对象 gameControl ,我想在调用方法重置并重新创建该对象时重新调用它,因为在中创建了很多引用gameControl 指向其他类。

我已经尝试做的事情如下:

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

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

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

reset是Commands中的函数,在Main中调用Commands,并在Main()中创建GameControl的对象。

请注意,重置会通过引用获取GameControl对象。

重置功能位于枚举器中,因此语法可能有点奇怪

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

预期结果是创建新对象时:

对象和对象引用值应清除。

实际结果:

不确定它是否是相同的对象,但是参考值仍然保存,所以我认为是。例如,在gameControl中创建了二维数组,并且在重新创建之后,该对象仍然存在并具有修改后的值。

谢谢!

2 个答案:

答案 0 :(得分:0)

Java是按值传递的。唯一的事情是,将值传递给方法时,对象引用作为值传递。因此,更改引用不会影响方法外部的引用。但是,由于您具有对对象的引用,因此可以在方法中使用来修改对象的状态。简单的例子来说明相同。关于同一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);
    }
}

答案 1 :(得分:0)

gameControl = null;
gameControl = new GameControl();

在分配新对象之前无需显式分配null。

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

没有种子可以调用垃圾收集器,这有两个原因。

首先,此调用只是要运行的垃圾收集器的 request ,而不是命令。垃圾收集器可能会或可能决定运行,并且可能会或可能不会立即完成其工作(可能会中断或重新安排,具体取决于特定垃圾收集器的实现细节)。

第二,垃圾回收不会影响先前指向对象A的gameControl变量的重新分配,而该变量现在指向对象B。重新分配立即发生。如果没有其他对象指向A,则A成为垃圾收集的候选对象。因此,您实际上并不关心现在还是以后收集A(意味着从内存中清除了)。您的应用不再知道A的存在。

示例应用

这是一个示例应用程序。为了方便起见,您可以将整个示例内容剪切并粘贴到单个.java文件中并执行。在真实的应用程序中,我将使用两个单独的.java文件,每个类一个。

请注意,我们的示例在此实例化了一个新的GameControl对象3次。每个新的GameControl都为其分配一个新的UUID作为标识符。这证明您每次都得到一个全新的GameControl

示例应用

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();
    }
}

运行时。

  

主要方法运行于2019-02-09T02:33:16.233414Z

     

GameControl的构造函数运行在:2019-02-09T02:33:16.265839Z

     

当前的GameControl id:4ee963c6-a895-4fe8-8463-b890777ad8f4

     

reset方法在以下位置运行:2019-02-09T02:33:16.280516Z

     

GameControl的构造函数运行于:2019-02-09T02:33:16.280796Z

     

当前的GameControl id:b74d9924-8f96-4321-9eca-a104642fc3f8

     

reset方法的运行时间为:2019-02-09T02:33:16.281139Z

     

GameControl的构造函数运行于:2019-02-09T02:33:16.281213Z

     

当前的GameControl id:3d8223c6-f93f-4708-832d-6cf60154befa