我正在尝试创建我的 Board 对象的副本,但它似乎没有实例化。有人可以告诉我为什么吗?
class Board {
private Board _copyBoard;
private int _size;
public Board (int N) {
_size = N;
}
public Board (Board b) {
this._copyBoard = b;
}
int size() {
return _size;
}
}
当我这样做时:
Board b = new Board(4);
Board x = new Board(b);
System.out.println(x.size()); --> 0 instead of 4.
复制构造函数通常应该复制实例变量,如有必要,应该复制一些深层状态 - 不保留对原始对象的引用。
你的getters和方法需要能够在对象自己的状态上,在它自己的变量中进行操作。到处都有某种双路径结构,if
语句要么转到你自己的变量,要么从中复制它的原始实例,这是糟糕的设计,而且非常复杂/低效。
public class Board {
protected int size;
protected Cell[][] grid;
public Board (int N) {
this.size = N;
// for example, create a 2D array.
this.grid = new Cell[size][size];
}
public Board (Board orig) {
this.size = orig.size();
// deep-copy the grid.
this.grid = new Cell[size][];
for (int i = 0; i < size; i++) {
grid[i] = Arrays.copyOf( orig.grid[i], size);
}
}
public int size() {return size;}
}
我非常喜欢protected
而不是私人,以获得更大的多功能性和工程访问。
我也不使用字段前缀,而是使用 this.
消除字段分配(在 setter 或其他方法中)的歧义。此方法非常适用于简单字段。
对于集合,我用列表或地图或其他任何东西为我的字段名称后缀; 参数命名时不带后缀。这使得复数运算和具有复数的方法调用变得清晰。例如,add (List<Customer> customers)
会将它们添加到字段customerList
。
Board b = new Board(4);
这将创建一个新板,其字段_size = 4
。
Board x = new Board(b);
这将创建一个新板,其字段_copyBoard = b
。
System.out.println(x.size());
这将打印出第二块板的现场_size
。您没有任何地方链接到第一块板的_size
变量。
你可以通过做
public Board (Board b) {
this._copyBoard = b;
}
int size() {
if(_copyBoard != null) {
return _copyBoard.size();
} else {
return _size;
}
}
考虑到所有因素,您可能正在查看数据的实际副本,而不是将这些类作为具有大量 if 语句的字段。
class Board {
private int _size;
public Board (int N) {
_size = N;
}
public Board (Board b) {
_size = b.size();
}
int size() {
return _size;
}
}
试试
Board b = new Board(4);
Board x = new Board(b);
System.out.println(x._size);
class Board {
public Board _copyBoard;
public int _size;
public Board (int N) {
this._size = N;
}
public Board (Board b) {
this._size = b._size;
}
int size() {
return _size;
}
}
在代码中,您不会将 size 的值复制到 x,而是将大小复制到 X 中的实例变量
如果将变量设为公共变量,则在代码中,则以下行将在代码中打印复制的值
System.out.println(x._copyBoard._size);