Думай на Java

Клонирование объектов


Наиболее часто клонирование применяется в тех случаях, когда в процессе работы метода необходимо внести изменения в объект, не изменяя при этом внешний объект. Для создания локальной копии объекта надо воспользоваться методом clone(). Это защищенный (protected) метод базового класса Object и все что от вас требуется, это переопределить его как public во всех классах, которые вы собираетесь клонировать. Например, переопределим метод clone() для класса стандартной библиотеки ArrayList, для дальнейшего использования clone() применительно к ArrayList:

//: Приложение А:Cloning.java

// Операция clone() работает только для

// нескольких элементов стандартной библиотеки Java.

import java.util.*;

class Int { private int i; public Int(int ii) { i = ii; } public void increment() { i++; } public String toString() { return Integer.toString(i); } }

public class Cloning { public static void main(String[] args) { ArrayList v = new ArrayList(); for(int i = 0; i < 10; i++ ) v.add(new Int(i)); System.out.println("v: " + v); ArrayList v2 = (ArrayList)v.clone(); // Увеличение всех элементов v2:

for(Iterator e = v2.iterator(); e.hasNext(); ) ((Int)e.next()).increment(); // Проверка изменения элементов v:

System.out.println("v: " + v); } } ///:~

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

В приведенном выше примере вы можете наблюдать результат поверхностного копирования, при котором операции, совершаемые с v2 отражаются на состоянии v:

v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

v: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Не следует использовать clone() для клонирования объектов, содержащихся в ArrayList, поскольку нет никаких гарантий что эти объекты будут клонируемыми (cloneable) [80].



Содержание раздела