在java中取消链接复制的实例变量

时间:2014-03-29 12:09:54

标签: java oop

我是java的新手,我希望能够更改其值已从其他实例复制的实例变量,并得到一些奇怪的结果。这是一些简单的代码

class DummyBean {

private Integer[] instant = new Integer[9];

private Integer state;

Integer[] getInstant() {
    return instant;
}

void setInstant(Integer[] arr) {
    for(int index =0;index<9;index++)
        this.instant[index] = arr[index];
}

Integer getState() {
    return state;
}

void setState(Integer state) {
    this.state = state;
}

public DummyBean(){
}
String getDummy() {
    return dummy;
}

void setDummy(String dummy) {
    this.dummy = dummy;
}

private String dummy;

public DummyBean(DummyBean another) {
    this.dummy = another.getDummy();
    this.instant = another.getInstant();
    this.state = another.getState();
}

public static void main(String[] args) throws CloneNotSupportedException {
    DummyBean dum = new DummyBean();
    Integer[] test = new Integer[9];
    for(int index =0;index<9;index++)
        test[index] = 1;
    dum.setInstant(test);
    dum.setState(10);

    System.out.println(dum.getInstant()[0]);
    System.out.println(dum.getState());

    DummyBean dumtwo = new DummyBean(dum);
    System.out.println(dumtwo.getInstant()[0]);
    System.out.println(dumtwo.getState());

    dum.getInstant()[0] = 2;
    dum.setState(20);
    System.out.println(dum.getInstant()[0]);
    System.out.println(dum.getState());
    System.out.println(dumtwo.getInstant()[0]);
    System.out.println(dumtwo.getState());

}

}

所以我得到

1
10

1
10


2
20

2
10

在最后两个值中,我了解dumtwo状态实例没有改变,但为什么dumtwo instant变量相应地更改为dum更改?

顺便说一下,为了让复制的dumtwo不能继承dum次更改,我们鞠躬致谢?

5 个答案:

答案 0 :(得分:2)

因为在你的拷贝构造函数中,dumdumtwo被引用到同一个数组,所以你没有在构造函数中复制数组:

public DummyBean(DummyBean another) {
    this.dummy = another.getDummy();
    this.instant = another.getInstant();
    this.state = another.getState();
}

因此,实例中任何对象的更改都会影响其他对象。

最后,您需要制作实例数组的新副本,以便使用:

System.arraycopy();

答案 1 :(得分:1)

在构造函数中,复制数组引用this.instant = another.getInstant();。由于数组是Object状态,因此可以修改。

IntegerString都是不可变的,因此复制引用很好。

您需要setInstant final

final void setInstant(Integer[] arr) {
    for(int index =0;index<9;index++)
        this.instant[index] = arr[index];
}

在构造函数中使用它:

public DummyBean(DummyBean another) {
    this.dummy = another.getDummy();
    setInstant(another.getInstant();
    this.state = another.getState();
}

或使用System.arraycopy()

P.S。请根据Java约定格式化和组织代码:

public class DummyBean {

    private Integer[] instant = new Integer[9];
    private Integer state;
    private String dummy;

    public DummyBean() {
    }

    public DummyBean(DummyBean another) {
        this.dummy = another.getDummy();
        setInstant(another.getInstant());
        this.state = another.getState();
    }

    Integer[] getInstant() {
        return instant;
    }

    final void setInstant(Integer[] arr) {
        for (int index = 0; index < 9; index++) {
            this.instant[index] = arr[index];
        }
    }

    Integer getState() {
        return state;
    }

    void setState(Integer state) {
        this.state = state;
    }

    String getDummy() {
        return dummy;
    }

    void setDummy(String dummy) {
        this.dummy = dummy;
    }
}

即。第一个变量声明。然后是构造函数。最后的方法。

答案 2 :(得分:1)

因为您引用instantdum的同一对象dumtwo。您可以在构造函数中执行的操作是

public DummyBean(DummyBean another) {
    this.dummy = another.getDummy();
    this.instant = setArrayCopy(another);
    this.state = another.getState();
}

private Integer[] setArrayCopy(DummyBean another){
    Integer[] arr = new Integer[9];
    for(int index =0;index<9;index++)
        arr[index] = another.getInstant()[index];
    return arr;
}

这是因为您可能不想让setInstant成为最终版本,并且当您的instant变量不是数组时会缩放,但是某些类会导致System.arraycopy()无法使用{{1}}

答案 3 :(得分:0)

您正在为DummyBean的两个实例引用相同的Integer数组。如果你想让每个人拥有自己的整数数组,你需要复制它。

答案 4 :(得分:0)

试试这个,你会得到答案:

    System.out.println(dum.instant.toString());
    System.out.println(dumtwo.instant.toString());