Tworzę kopię mojego obiektu za pomocą metody clone(). Ale kiedy następuje modyfikacja w kopii, oryginalny obiekt jest również modyfikowany. Próbowałem powtórzyć mój problem w poniższym przykładzie. Oto 2 klasy ClassA i ClassB.

public class ClassB implements Cloneable
{
    int num = 0;

    byte[] bit = new byte[1];

     //Getters and setters have been removed due to space constraint

            public Object clone() 
    {
        try
        {   
          ClassB obj = (ClassB)super.clone();

          obj.setNum(this.num);
               obj.setBit(this.bit);

          return obj;
        } catch (CloneNotSupportedException e) {
                return null;              }
    }
}

//Oto Klasa A, która zawiera główną metodę i używa klonu

public class ClassA {

    public void cloneMethod(){

        ClassB objB = new ClassB();
        objB.bit[0] = (byte)0x8;
        objB.setNum(5);     

        ClassB objCopy = null;
        objCopy = (ClassB) objB.clone();

        if(objCopy.bit[0] != (byte)0x0)
        {
            objCopy.bit[0] = 0;
        }

        System.out.println(objB.bit[0]); //At this point the original object    value is also modified.

    }

    public static void main(String args[])
    {
        ClassA a = new ClassA();
        a.cloneMethod();
    }

}

Jak zachować pierwotną wartość obiektu? Wiem, że klon ma pewne wady. Próbowałem również z nowym słowem kluczowym, ale to nie pomaga. Proszę zasugerować. w moim oryginalnym kodzie muszę użyć oryginalnej wartości bitowej obiektu później do dalszych obliczeń, a wartość bitu obiektu kopii wyniesie 0. Dzięki.

0
JavaBits 10 sierpień 2011, 14:58

3 odpowiedzi

Najlepsza odpowiedź

Nie ustawiaj bit na ten sam byte[] co oryginalny obiekt, zamiast tego sklonuj go również:

obj.bit = this.bit.clone();

Nie musisz też ustawiać num, ponieważ będzie to już ustawione poprawnie dla obiektu zwróconego przez super.clone().

1
Joachim Sauer 10 sierpień 2011, 15:03
1
@JavaBits: To jest dokładnie to, czego potrzebujesz, głęboka kopia!
 – 
home
10 sierpień 2011, 15:06
Tak, właśnie dowiedziałem się tego samego. Wielkie dzięki. Działa idealnie.
 – 
JavaBits
10 sierpień 2011, 15:17
IMHO, najbardziej użyteczna semantyka metody „klonowania”, zwłaszcza dla klasy ogólnej, nie powinna być głęboką kopią, ale raczej czymś, co nazwałbym kopią „na poziomie semantycznym”. Klon FooCollection powinien być nowym FooCollection zawierającym te same T co oryginały; mutacje wykonane na oryginalnym FooCollection nie powinny wpływać na klon, ale mutacje wykonane na T w oryginalnej kolekcji powinny wpływać na T widoczne w klonie (ponieważ powinny to być te same T). Zasadniczo zachowanie sklonowanego FooCollection nie powinno zależeć od tego, jak...
 – 
supercat
10 sierpień 2011, 20:44
...sam FooCollection przechowuje rzeczy (niezależnie od tego, czy używa tablicy, tablic zagnieżdżonych, połączonej listy, czy czegokolwiek), ale zamiast tego FooCollection powinien zachowywać się tak, jakby był pojedynczym blokiem, który zawiera niezależne T. Nie znam żadnego konkretnego terminu opisującego taką semantykę; gdybym miał swój druther, ten styl klonowania byłby „płytką kopią”, podczas gdy wszystko, co płytsze, byłoby nazywane „uszkodzoną kopią”, ale ponieważ termin „płytka kopia” jest często używany w odniesieniu do tego, co ja nazwałbym „uszkodzoną kopią”. kopiuj”, nie jestem pewien, jaki byłby najlepszy termin.
 – 
supercat
10 sierpień 2011, 20:46
obj.setNum(this.num);
obj.setBit(this.bit);

Te dwie linie kodu są (a) nadmiarowe i (b) błędne. Jeśli chcesz tylko oryginalnych wartości pól w klonie, wcale tego nie potrzebujesz, ponieważ super.clone() już to zrobiła. Jeśli Twoim celem jest zwrot przedmiotu o niezależnej wartości. Ponieważ bit[] jest tablicą, tj. Obiektem, należy go również sklonować.

1
user207421 12 sierpień 2011, 03:30

Nie klonujesz swojej tablicy bit.

0
Alexander Pogrebnyak 10 sierpień 2011, 15:04