Java 引用传递不起作用?
Java Pass-by-reference not working?
我正试图在 Java 中制作这个小游戏,但我似乎偶然发现了一个变量引用问题。
我的实体 class 是 Player 的扩展,它保留了一个 Dimension 类型的变量。
这个维度通过实体的构造函数设置 class 像这样:
protected Dimension dimension;
public Entity(Dimension dimension) {
this.dimension = dimension;
}
在我的播放器 class 中,这是我通过他的构造函数传递维度对象的方式:
public Player(Dimension dimension) {
super(dimension);
}
我还有一个游戏 class,它保留所有可能的维度,以及一个名为 activedimension 的额外变量,它保留对活动游戏维度的引用。
private Dimension activedimension;
private Dimension overworld;
private Dimension otherdimension;
public Game() {
overworld = new OverWorldDimension();
otherdimension = new OtherDimension();
activedimension = overworld;
}
当我想要重置主世界维度时,我使用这个方法:
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension = overworld;
}
现在,每当我从任何地方调用此 resetOverWorld 方法时,似乎我的 activedimension 确实刷新了,但存储在 Player/Enitity class 中的维度却没有。
我是 Java 的新手,所以我不知道通过构造函数和方法传递的变量引用是否有问题。
我的应用程序似乎在某处复制了一个维度对象而不是传递引用,但我不知道在哪里。
欢迎任何帮助或想法。
提前致谢
~克里克
您不保存对变量 overworld 的引用,而是保存对 overworld 值的引用:
this.dimension = dimension;
因此当游戏中的引用发生变化时,您必须手动更新实体的引用,否则它将指向旧值,因为它独立于变量 overworld。
您将一个维度对象传递给您的 Player
对象,它在其字段之一中存储对该对象的引用。
在您的 Game
对象中,您将 activedimension
设置为引用 Dimension
对象。通过更改其值,您可以将其更改为引用不同的 Dimension
对象。
即使 activedimension
用于引用您传递给 Player
的同一个 Dimension
对象,将其更改为不同的 Dimension
对象也不会改变哪个对象是在 Player
.
中引用
考虑一下,如果系统启动是这样的:
Game
- activedimension --> Dimension object A
Player
- dimension --> Dimension object A
Dimension object A
的更改将被 Player
和 Game
对象看到。
但是,将 activedimension
更改为指向 Dimension object B
,一个完全不同的对象不会使 dimension
更改为指向它。
Game
- activedimension --> Dimension object A
Player
- dimension --> Dimension object B
问题是您没有更新 Player
class 中的引用。当您将 Dimension
存储在 Entity
构造函数中时,您是在内存中存储对该 Dimension
的引用。在您的 resetOverWorld()
方法中,您将 overworld
和 activedimension
变量更改为指向新的 OverWorldDimension
但其他地方的所有引用(例如您的 Entity
对象)都没有改变了。他们仍然参考最初的Dimension
他们被构造。
您可能需要考虑使用 DimensionTracker
class 代替您的 Entity
,这样您就可以从一个位置更改它的内部 Dimension
。否则你需要更新每个 Entity
以引用新的 Dimension
.
public class DimensionTracker {
public Dimension dimension;
public DimensionTracker(Dimension d) {
dimension = d;
}
}
...
protected DimensionTracker dimensionTracker;
public Entity(DimensionTracker dt) {
dimensionTracker = dt;
}
...
public Player(DimensionTracker dt){
super(dt);
}
...
private DimensionTracker activedimension;
private Dimension overworld;
private Dimension otherdimension;
public Game() {
overworld = new OverWorldDimension();
otherdimension = new OtherDimension();
activedimension.dimension = overworld;
}
...
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension.dimension = overworld;
}
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension = overworld;
}
这只会更新游戏 class 变量 private Dimension activedimension ;
调用 resetOverWorld()
后,您必须通过执行
之类的操作来设置对实体 class 的新引用
entity.setDimension(activedimension)
我正试图在 Java 中制作这个小游戏,但我似乎偶然发现了一个变量引用问题。 我的实体 class 是 Player 的扩展,它保留了一个 Dimension 类型的变量。 这个维度通过实体的构造函数设置 class 像这样:
protected Dimension dimension;
public Entity(Dimension dimension) {
this.dimension = dimension;
}
在我的播放器 class 中,这是我通过他的构造函数传递维度对象的方式:
public Player(Dimension dimension) {
super(dimension);
}
我还有一个游戏 class,它保留所有可能的维度,以及一个名为 activedimension 的额外变量,它保留对活动游戏维度的引用。
private Dimension activedimension;
private Dimension overworld;
private Dimension otherdimension;
public Game() {
overworld = new OverWorldDimension();
otherdimension = new OtherDimension();
activedimension = overworld;
}
当我想要重置主世界维度时,我使用这个方法:
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension = overworld;
}
现在,每当我从任何地方调用此 resetOverWorld 方法时,似乎我的 activedimension 确实刷新了,但存储在 Player/Enitity class 中的维度却没有。 我是 Java 的新手,所以我不知道通过构造函数和方法传递的变量引用是否有问题。 我的应用程序似乎在某处复制了一个维度对象而不是传递引用,但我不知道在哪里。
欢迎任何帮助或想法。 提前致谢 ~克里克
您不保存对变量 overworld 的引用,而是保存对 overworld 值的引用:
this.dimension = dimension;
因此当游戏中的引用发生变化时,您必须手动更新实体的引用,否则它将指向旧值,因为它独立于变量 overworld。
您将一个维度对象传递给您的 Player
对象,它在其字段之一中存储对该对象的引用。
在您的 Game
对象中,您将 activedimension
设置为引用 Dimension
对象。通过更改其值,您可以将其更改为引用不同的 Dimension
对象。
即使 activedimension
用于引用您传递给 Player
的同一个 Dimension
对象,将其更改为不同的 Dimension
对象也不会改变哪个对象是在 Player
.
考虑一下,如果系统启动是这样的:
Game
- activedimension --> Dimension object A
Player
- dimension --> Dimension object A
Dimension object A
的更改将被 Player
和 Game
对象看到。
但是,将 activedimension
更改为指向 Dimension object B
,一个完全不同的对象不会使 dimension
更改为指向它。
Game
- activedimension --> Dimension object A
Player
- dimension --> Dimension object B
问题是您没有更新 Player
class 中的引用。当您将 Dimension
存储在 Entity
构造函数中时,您是在内存中存储对该 Dimension
的引用。在您的 resetOverWorld()
方法中,您将 overworld
和 activedimension
变量更改为指向新的 OverWorldDimension
但其他地方的所有引用(例如您的 Entity
对象)都没有改变了。他们仍然参考最初的Dimension
他们被构造。
您可能需要考虑使用 DimensionTracker
class 代替您的 Entity
,这样您就可以从一个位置更改它的内部 Dimension
。否则你需要更新每个 Entity
以引用新的 Dimension
.
public class DimensionTracker {
public Dimension dimension;
public DimensionTracker(Dimension d) {
dimension = d;
}
}
...
protected DimensionTracker dimensionTracker;
public Entity(DimensionTracker dt) {
dimensionTracker = dt;
}
...
public Player(DimensionTracker dt){
super(dt);
}
...
private DimensionTracker activedimension;
private Dimension overworld;
private Dimension otherdimension;
public Game() {
overworld = new OverWorldDimension();
otherdimension = new OtherDimension();
activedimension.dimension = overworld;
}
...
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension.dimension = overworld;
}
public void resetOverWorld() {
overworld = new OverWorldDimension();
activedimension = overworld;
}
这只会更新游戏 class 变量 private Dimension activedimension ;
调用 resetOverWorld()
后,您必须通过执行
entity.setDimension(activedimension)