java - 为什么对象数组中的元素没有更新?
问题描述
在使用 JavaFX 创建应用程序时,我遇到了一个小问题 - 我的数组中的元素不知何故不会随着对这些元素所做的更改而更新。一开始我想指出 - 不要关注我的应用程序的结构和模型 - 我已经知道它不好,我改变了它,但我仍然不明白为什么我的问题存在。我的数组的初始化如下所示:
public class GameBoardAI implements IGameModel{
Random rand = new Random();
int currentPlayer = 1;
TicTacViewController tacController = new TicTacViewController();
Button[] buttonss = new Button[]{ tacController.btn1, tacController.btn2, tacController.btn3, tacController.btn4,
tacController.btn5, tacController.btn6, tacController.btn7, tacController.btn8, tacController.btn9};
问题是,当我创建按钮数组时,按钮还没有连接到视图,所以它们仍然是空值。当我试图在里面的按钮上调用一些方法时,我遇到了一个问题:
public void switchPlayer() {
if(currentPlayer == 1)
{
currentPlayer=2;
buttonss[rand.nextInt(9)].fire();
}
if(currentPlayer == 2)
currentPlayer = 1;
}
您可以在这里看到,我正在尝试从我在实例变量中创建的按钮数组中获取一些随机按钮。这是代码的一部分,当按钮位于 TicTacViewController 中时:
public class TicTacViewController implements Initializable
{
@FXML
private Label lblPlayer;
@FXML
private Button btnNewGame;
@FXML
private GridPane gridPane;
private static final String TXT_PLAYER = "Player: ";
private IGameModel game = new GameBoard();
@FXML
public Button btn1;
@FXML
public Button btn2;
@FXML
public Button btn3;
@FXML
public Button btn4;
@FXML
public Button btn5;
@FXML
public Button btn6;
@FXML
public Button btn7;
@FXML
public Button btn8;
@FXML
public Button btn9;
据我了解,问题是,当我将数组创建为实例变量时,mu 按钮仍然为空 - 它们尚未连接到视图。但是这里发生了一些奇怪的事情:当我将数组初始化放在 switchPlayer 方法中而不是作为实例变量执行时 - 一切正常。因此,当我在调用方法时创建数组时,似乎按钮已经连接到视图并且没有问题。它破坏了我对引用变量的了解——为什么当我们将数组创建为实例变量时它不起作用?因为我认为即使我们在数组中有引用变量——当我们改变这个引用变量时,它们也会在我们的数组中改变。更具体地说 - 即使我们正在初始化一个数组并且按钮尚未连接到视图,它们之后也会连接 - 所以当我们调用 switchPlayer 方法时,按钮应该已经连接到视图 - 但编译器告诉我他们是空的。有人可以解释一下这里有什么问题吗?为什么在调用方法时按钮仍然为空,因为它们是在创建数组时,即使它们后来连接到视图?
解决方案
Java 是一种按值传递的语言。对象类型变量不是对象指针,它们只是保存一个对象引用(即内存地址)。例子:
String str = "Hello"; // A String type variable holding reference of "Hello" string
String str2 = str; // Variable "str2" now copies the reference of "str"
String str2 = "World"; // Variable "str2" changes the reference it holds to the string "World" (in other word, it is being replaced)
它经常被混淆,因为以下是有效的:
List<String> foo = new ArrayList<>(); // Let foo hold the reference of an empty arraylist
List<String> bar = foo; // Let bar hold the reference that is held by foo
bar.add("hello");
System.out.println(foo); // Prints "[hello]"
这是有效的,因为bar
已经复制了ArrayList
from的对象引用,因此对viafoo
的任何操作都将由 反映,因为它们都持有相同的对象引用。ArrayList
bar
foo
回到你的问题。如果tacController
没有加载 FXML 文件,所有的Button
引用都将是null
. 所以你要做的是复制null
引用并将这些null
引用保存在数组中。因此,您将永远无法访问实际Button
对象。
推荐阅读
- javascript - 从 API 获取数据后如何在数组中渲染单个对象?
- reactjs - 如何在 typescript+webpack 项目中使用 js/jsx 文件?
- reactjs - 警告:上下文类型失败:上下文“可见”被标记为必需,但其值为“未定义”
- github - 我应该如何更正我的链接代码以便它可以在 Github 上运行?
- android-studio - 面临错误>>无法解决方法'with(匿名com.android.volley.Response.Listner
)' - python - Python中的索引错误
- python - 模板语言的 Django 不工作/呈现任何数据
- javascript - 使 ReactMarkdown 组件可编辑
- assembly - 为什么 GDB 检查结果会根据我是否事先检查字符串而有所不同?
- python - 我在 python 上安装 Pyaudio 时失败了