5

在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)总是得到不同值的输出。这意味着aPolynomialget 在运行时的某个地方发生了变化。

更改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()oftempaPolynomial确实会产生两个不同的值。

aPolynomial在循环hashCode的每次运行中都有相同的。for

评论中一些问题的答案:

因为Polynomial不从任何地方继承,就我而言,我super.clone()会提到Object

我有我自己的toString方法。

4

2 回答 2

7

我相信您遇到的问题是:您验证了temp的克隆aPolynomial实际上是一个单独的对象。但是您从该对象使用的值在引用中temp.pol。在 clone 方法期间,该引用被复制到新Polynomial实例,以便两者aPolynomialtemp引用同一个对象及其pol成员。

最简单的解决方案是实现自定义 clone() 方法,您还可以在其中克隆polPolynomial.

类似于以下内容:

public Polynomial clone() {
    try {
        Polynomial p = (Polynomial)super.clone();
        p.pol = this.pol.clone();
        return p;
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return null;
}
于 2013-10-18T18:56:47.223 回答
4

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

你应该做一个 deep copy() 这也将创建你的成员的一个新实例(我猜你的情况是元组),这样它们就不会指向相同的对象。这你必须自己实现。

据说使用 clone() 被认为是不好的做法,你不应该这样做(为什么,你可以谷歌它,特别是寻找 Bloch 的 clone() 与复制构造函数)。除了复制构造函数(这样一个构造函数,它接受与它构造的对象相同类型的参数并将其用作模板),还有特殊的深度复制库。或者您可以序列化您的对象并以这种方式复制它们,但前提是您喜欢这种困难的方式。

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

于 2013-10-18T18:58:34.653 回答