我创建了一个具有两个属性的Robot类:direction(它只是一个字符串E,A,S,N)和location(一个4个整数的数组,用于保持两个方向上的位置)。该类有主要构造函数:
public Robot (int east, int north, int west, int south, int direction) {
this.direction = direction%4 ;
location = new int[4] ;
int[] location = {east,north,west,south} ; }
复制构造函数:
Robot( Robot copy ) {
direction = copy.direction ;
location = copy.location ;
}
它也有方法,但我想展示这两个方法:move()和setDirection()。
public void move() {
location[direction]++ ;
}
public void setDirection( int direction ) {
this.direction = direction ;
}
我创建了一个Robot对象并将其均衡为一个新对象,并使用另一个新对象并使用了复制构造函数:
Robot terminator = new Robot(0,0,0,0,1) ;
Robot b = terminator ;
Robot a = new Robot(terminator) ;
这是问题所在,当我对终结符a,b使用move()方法时,其他人的位置都会发生变化但是当我使用setDirection作为终结符时,a不会改变但是b会发生变化。此外,当我使用相同的a时,b和终结器的方向都不会改变。那么区别是什么呢?为什么在终结器上实现的move()方法会影响副本,但是当使用setDirection()时它不会?
System.out.println(terminator) ;
System.out.println(a) ;
System.out.println(b) ;
terminator.setDirection(2);
a.setDirection(3) ;
terminator.move() ;
System.out.println(terminator) ;
System.out.println(a) ;
System.out.println(b) ;
输出:
Location[0, 0, 0, 0]Direction N
Location[0, 0, 0, 0]Direction N
Location[0, 0, 0, 0]Direction N
Location[0, 0, 1, 0]Direction W
Location[0, 0, 1, 0]Direction S
Location[0, 0, 1, 0]Direction W
答案 0 :(得分:0)
两个Robot
个实例都包含对同一位置int[]
的引用。您需要在创建新的Robot
实例时创建新数组,例如,使用Arrays.copyOf
:
Robot( Robot copy ) {
direction = copy.direction ;
location = Arrays.copy(copy.location, copy.location.length);
// Here ---^
}
答案 1 :(得分:0)
看看你的构造函数:
Robot( Robot copy ) {
direction = copy.direction ;
location = copy.location ;
}
你在这里做浅色复制。
您的direction
是原始类型,因此您复制的Robot
会获得原始Robot
方向值的副本。它们与direction
变量
与此同时,您的location
是一个数组,因此您复制的Robot
会获得对原始Robot
位置的引用。 Robot
都有相同的location
数组。改为一个影响另一个。
如果要分隔两个Robot
实例,则必须deep copy
数组location
。
而不是:
location = copy.location;
做:
location = Arrays.copyOf(copy.location, copy.location.length);