为什么对象数组中的元素未更新?

时间:2018-10-23 07:32:01

标签: java javafx

在使用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};  

问题是,当我创建按钮数组时,按钮尚未连接到视图,因此它们仍为null。当我尝试在内部按钮上调用某些方法时,遇到了一个问题:

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方法时,按钮应该已经连接到视图-但是编译器告诉我他们为空。有人可以告诉我这里是什么问题吗?为什么在调用方法按钮时仍然像在数组创建中那样仍然为空,即使它们后来连接到视图也是如此?

1 个答案:

答案 0 :(得分:1)

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复制了foo的对象引用,因此将反映通过ArrayListbar的任何操作。 foo编写,因为它们都拥有相同的对象引用。

回到您的问题。如果tacController尚未加载FXML文件,则所有Button引用都将是null。因此,您要做的是复制null引用并将这些null引用保留在数组中。因此,您将永远无法访问实际的Button对象。