четверг, 10 ноября 2011 г.

Коротко о clone()

Метод clone() в Java используется для(подожди-подожди...) клонирования объектов. Т.к. Java работает с объектами с помощью ссылок, то простым присваиванием тут не обойдешься, ибо в таком случае копируется лишь адрес, и мы получим две ссылки на один и тот же объект, а это не то, что нам нужно. Механизм копирования обеспечивает метод clone() класса Object.
clone() действует как конструктор копирования. Обычно он вызывает метод clone() суперкласса и т.д. пока не дойдет до Object.


Метод clone() класса Object создает и возвращает копию объекта с такими же значениями полей. Object.clone() кидает исключение CloneNotSupportedException если вы пытаетесь клонировать объект не реализующий интерфейс Cloneable. Реализация по умолчанию метода Object.clone() выполняет неполное/поверхностное (shallow) копирование. Если вам нужно полное/глубокое (deep) копирование класса то в методе clone() этого класса, после получения клона суперкласса, необходимо скопировать нужные поля.
Синтаксис вызова clone() следующий:
Object copy = obj.clone();

или чаще:
MyClass copy = (MyClass) obj.clone();

Один из недостатков метода clone(), это тот факт, что возвращается тип Object, поэтому требуется нисходящее преобразование типа. Однако начиная с версии Java 1.5 при переопределении метода вы можете сузить возвращаемый тип.
Пару слов о clone() и final полях.
Метод clone() несовместим с final полями. Если вы попробуете клонировать final поле компилятор остановит вас. Единственное решение - отказаться от final.
Ну и пример использования clone():
class MyClass implements Cloneable{
    public Integer i = 10;
    public MyClass clone() throws CloneNotSupportedException{
        MyClass obj=(MyClass)super.clone();
        obj.i = i;
        return obj;
    }
    public String toString(){
        return i.toString();
    }
}

public class Temp {
    public static void main(String []args) throws  CloneNotSupportedException{
        MyClass a = new MyClass();
        a.i = 11;
        MyClass b = a.clone();
        MyClass c = a;
        System.out.println("a: " + a + " b: " + b + " c: " + c);
        a.i=12;
        System.out.println("a: " + a + " b: " + b + " c: " + c);
    }
} 

Консоль:
a: 11 b: 11 c: 11
a: 12 b: 11 c: 12

Как видите, изменение объекта a повлекло за собой изменение объекта c, а вот с b всё в порядке.

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.