为什么clone()不能按预期工作?

时间:2013-10-18 18:28:14

标签: java clone

在java中使用以下代码

public Polynomial multiply(Polynomial aPolynomial){
    Polynomial ret = new Polynomial();
    for (Tuple i: this.pol){
        Polynomial temp = aPolynomial.clone();
        System.out.print(temp);
        for (Tuple j: temp.pol){
            j.setCoef(j.getCoef() * i.getCoef());
            j.setPower(j.getPower() + i.getPower());
        }
        ret = ret.add(temp).clone();
    }       
    return ret;
}

我得到System.out.print(temp)的输出总是不同的值。这意味着aPolynomial在运行时在某处被改变了。

Polynomial temp = aPolynomial.clone();更改为:

LinkedList<Tuple> list1 = (LinkedList<Tuple>) aPolynomial.pol.clone();
Polynomial temp = new Polynomial(list1);

没有帮助System.out.print(temp)的输出在每次循环运行时都有所不同。

我的错误在哪里?

编辑:

public Polynomial clone() {
    try {
        return (Polynomial)super.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return null;
}

打印hashCode() tempaPolynomial会产生两个不同的值。

aPolynomialhashCode循环的每次运行中都有相同的for

回答评论中的一些问题:

由于Polynomial不会从任何地方继承,因此我关注super.clone()会引用Object

我有自己的toString方法。

2 个答案:

答案 0 :(得分:6)

我相信您遇到的问题是:您确认tempaPolynomial的克隆,实际上是一个单独的对象。但是您从该对象使用的值位于引用temp.pol中。在克隆方法期间,该引用将被复制到新的Polynomial实例,以便aPolynomialtemp引用与pol成员相同的对象。< / p>

最简单的解决方案是实现自定义clone()方法,您还可以克隆pol对新Polynomial实例的引用。

有些事情:

public Polynomial clone() {
    try {
        Polynomial p = (Polynomial)super.clone();
        p.pol = this.pol.clone();
        return p;
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return null;
}

答案 1 :(得分:3)

我很确定Java的Object#clone()默认执行浅拷贝。这意味着它将创建对象的新实例(所以“x.clone()!= x”),但会直接复制成员字段。这意味着如果您将引用作为成员,则将复制地址而不是值。因此,您有一个内部指向相同对象的克隆。当您更改克隆中对象的状态时,它等于更改原始对象的状态。

你应该做一个深拷贝(),它也会创建你的成员的新实例(我想你的元组),所以他们不指向相同的对象。你必须自己实现。

据说使用clone()被视为不良做法,你不应该这样做(为什么,你可以Google,特别是寻找Bloch的clone()vs copy constructor)。除了复制构造函数(所以构造函数采用与它构造的对象相同类型的参数并将其用作模板)之外,还有特殊的深度复制库。或者你可以通过序列化你的对象并以这种方式复制它们,但这只有你喜欢的方式。

@Edit:这里有一些采访,他在那里谈了一点http://www.artima.com/intv/bloch13.html。有关他的全文,您需要参考Effective Java 2nd Edition