【问题标题】:An Issue of Copy Constructor拷贝构造函数的问题
【发布时间】:2018-11-05 13:47:25
【问题描述】:

我创建了一个具有两个属性的机器人类:方向(它只是一个字符串 E、A、S、N)和位置(一个由 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 和终止符的方向都不会改变。那么区别是什么呢?为什么在 terminator 上实现的 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

【问题讨论】:

    标签: java class oop copy-constructor


    【解决方案1】:

    看看你的构造函数:

    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);
    

    【讨论】:

    • 感谢您的帮助,现在我明白其中的逻辑了。
    【解决方案2】:

    两个Robot 实例都持有对同一位置int[] 的引用。在创建新的Robot 实例时需要创建一个新数组,例如,使用Arrays.copyOf

    Robot( Robot copy ) {
        direction = copy.direction ;
        location = Arrays.copy(copy.location, copy.location.length);
        // Here ---^
    }
    

    【讨论】:

    • 谢谢你的回答我知道了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 2012-11-11
    • 2013-03-19
    相关资源
    最近更新 更多