Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why clone() doesn't work as expected?

Tags:

java

clone

Having the following code in 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;
}

I get as output for System.out.print(temp)always different values. This means that aPolynomialget's altered somewhere during runtime.

Changing Polynomial temp = aPolynomial.clone(); to:

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

doesn't help either the output for System.out.print(temp) being also different on every run of the loop.

Where is my mistake?

Edit:

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

printing the hashCode() of temp and aPolynomial does result in two different values.

aPolynomial does have the same hashCode on every run of the for loop.

answers to some question in the comments:

since Polynomialdoesn't inherit from anywhere, as far as I ma concerned super.clone() will refer to Object

I do have my own toString method.

like image 472
Alexandru Barbarosie Avatar asked Oct 18 '13 18:10

Alexandru Barbarosie


1 Answers

I believe the problem you are experiencing is this: You verified that temp, the clone of aPolynomial, is actually a separate object. But the values you are using from that object are in the reference temp.pol. During the clone method, that reference is being copied over to the new Polynomial instance, so that both aPolynomial and temp refer to the same object with their pol member.

The easiest solution would be to implement a custom clone() method where you also clone the pol reference to the new instance of Polynomial.

Something along the lines of:

public Polynomial clone() {
    try {
        Polynomial p = (Polynomial)super.clone();
        p.pol = this.pol.clone();
        return p;
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return null;
}
like image 175
NemesisX00 Avatar answered Nov 15 '22 05:11

NemesisX00