二维整数数组值丢失求助:GameSetting赋值后仅保留最后一个值
问题:多个按钮实例独立操作不同的GameSetting数组,导致数据丢失
我定义了GameSetting类管理3x3游戏数组,提供赋值和获取数组的方法:
public class GameSetting { private int[][] gameArray; public GameSetting(){ gameArray = new int[3][3]; } public void setValue(int i, int j, int value){ this.gameArray[i][j] = value; } public int[][] getGameArray(){ return this.gameArray; }
但MyButton类中每个按钮实例都创建了独立的GameSetting对象:
public class MyButton extends Button { private int x; private int y; private int k; private int g; private int coordinateA; private int coordinateB; private GameSetting gameSettings = new GameSetting(); // 每个按钮新建独立实例 public MyButton(String name, int x, int y, int k, int g, int coordinateA, int coordinateB) { super(name); this.setLayoutX(x); this.setLayoutY(y); this.setPrefHeight(121); this.setPrefWidth(121); this.setOpacity(0.5); this.setCursor(Cursor.CLOSED_HAND); this.x = x; this.y = y; this.k = k; this.g = g; this.coordinateA = coordinateA; this.coordinateB = coordinateB; } public void clickToPlay() { this.setOnAction(event -> { Parent parent = this.getParent(); if(parent instanceof Group){ ((Group) parent).getChildren().remove(this); if(HelloApplication.whichPlayer%2 == 0) { GameImage imageViewCross = new GameImage(HelloApplication.circle, this.k, this.g); gameSettings.setValue(coordinateA, coordinateB, 1); ((Group) parent).getChildren().add(imageViewCross); }else{ GameImage imageViewCircle = new GameImage(HelloApplication.cross, this.k, this.g); gameSettings.setValue(coordinateA, coordinateB, 2); ((Group) parent).getChildren().add(imageViewCircle); } HelloApplication.whichPlayer++; if(HelloApplication.whichPlayer == 9){ int[][] test = gameSettings.getGameArray(); for (final int[] is : test) { System.out.println(Arrays.toString(is)); } } } }); } }
每次点击按钮时,赋值操作都在各自的GameSetting实例中进行,最终只能获取当前按钮实例里的最后一次赋值,其他按钮的操作数据全部丢失。需要让所有按钮共享同一个GameSetting实例,统一操作同一个二维数组。
解决方案
方法1:构造函数注入(推荐,解耦性好)
修改MyButton类,不再内部创建GameSetting实例,而是通过构造函数传入全局唯一的GameSetting对象:
- 修改
MyButton的成员变量和构造函数:
public class MyButton extends Button { private GameSetting gameSettings; // 改为外部传入的成员变量 // 其他成员变量保持不变 // 构造函数新增GameSetting参数 public MyButton(String name, int x, int y, int k, int g, int coordinateA, int coordinateB, GameSetting gameSettings) { super(name); this.setLayoutX(x); this.setLayoutY(y); this.setPrefHeight(121); this.setPrefWidth(121); this.setOpacity(0.5); this.setCursor(Cursor.CLOSED_HAND); this.x = x; this.y = y; this.k = k; this.g = g; this.coordinateA = coordinateA; this.coordinateB = coordinateB; this.gameSettings = gameSettings; // 接收全局实例 } // clickToPlay方法逻辑不变 }
- 在初始化按钮时,传入同一个
GameSetting实例:
// 在HelloApplication或初始化入口创建全局唯一实例 GameSetting globalGameSetting = new GameSetting(); // 创建所有按钮时都传入该实例 MyButton btn00 = new MyButton("btn00", 0, 0, 0, 0, 0, 0, globalGameSetting); MyButton btn01 = new MyButton("btn01", 121, 0, 121, 0, 0, 1, globalGameSetting); // 其他按钮同理
方法2:给GameSetting实现单例模式
让GameSetting自身保证全局只有一个实例,所有按钮都获取该单例操作数组:
修改GameSetting为单例:
public class GameSetting { private int[][] gameArray; private static GameSetting instance; // 私有构造函数,禁止外部直接实例化 private GameSetting(){ gameArray = new int[3][3]; } // 全局获取唯一实例的方法 public static GameSetting getInstance(){ if(instance == null){ instance = new GameSetting(); } return instance; } // setValue和getGameArray方法保持不变 public void setValue(int i, int j, int value){ this.gameArray[i][j] = value; } public int[][] getGameArray(){ return this.gameArray; } }
修改MyButton获取单例实例:
public class MyButton extends Button { private GameSetting gameSettings; public MyButton(String name, int x, int y, int k, int g, int coordinateA, int coordinateB) { super(name); // 其他初始化代码不变 this.gameSettings = GameSetting.getInstance(); // 获取全局单例 } // clickToPlay方法逻辑不变 }
方法3:使用静态数组(简单直接,灵活性差)
把GameSetting中的数组改为静态变量,让所有实例共享同一个数组:
修改GameSetting类:
public class GameSetting { // 改为静态数组,所有实例共享 private static int[][] gameArray = new int[3][3]; public GameSetting(){ // 无需再初始化数组,静态变量已默认初始化 } public void setValue(int i, int j, int value){ gameArray[i][j] = value; } public int[][] getGameArray(){ return gameArray; } }
这种方式下,即使每个MyButton创建自己的GameSetting实例,操作的都是同一个静态数组,数据不会丢失。但静态变量扩展性差,后续如果需要支持多局游戏场景,该方式不适用。
内容的提问来源于stack exchange,提问作者Karlz-Bandz
相关产品推荐
相关产品推荐

