在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()
temp
和aPolynomial
会产生两个不同的值。
aPolynomial
在hashCode
循环的每次运行中都有相同的for
。
回答评论中的一些问题:
由于Polynomial
不会从任何地方继承,因此我关注super.clone()
会引用Object
我有自己的toString
方法。
答案 0 :(得分:6)
我相信您遇到的问题是:您确认temp
,aPolynomial
的克隆,实际上是一个单独的对象。但是您从该对象使用的值位于引用temp.pol
中。在克隆方法期间,该引用将被复制到新的Polynomial
实例,以便aPolynomial
和temp
引用与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