我有一个对象 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中创建了二维数组,并且在重新创建之后,该对象仍然存在并具有修改后的值。
谢谢!
答案 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