Класс Object в Java содержит стандартный метод clone()
, который возвращает копию существующего объекта. Сегодня мы рассмотрим пример использования этого метода и разберем сложные моменты, связанные с клонированием объектом.
Для использования клонирования в Java вам нужно реализовать интерфейс java.lang.Cloneable
, иначе будет брошено исключение CloneNotSupportedException
.
Давайте рассмотри представленный ниже Java класс:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
package ua.com.prologistic; import java.util.HashMap; import java.util.Iterator; public class CloneTest implements Cloneable { private int id; private String name; private HashMap props; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public HashMap getProps() { return props; } public void setProps(HashMap props) { this.props = props; } /* public CloneTest clone() { System.out.println("Вызываем переопределенный метод clone()"); HashMap hm = new HashMap(); String key; Iterator it = this.props.keySet().iterator(); // глубокое копирование объекта Java while (it.hasNext()) { key = it.next(); hm.put(key, this.props.get(key)); } CloneTest ct = new CloneTest(); ct.setId(this.id); ct.setName(this.name); ct.setProps(hm); return ct; } */ public static void main(String[] args) throws CloneNotSupportedException { CloneTest ct1 = new CloneTest(); ct1.setId(1); ct1.setName("первый"); HashMap hm = new HashMap(); hm.put("1", "first"); hm.put("2", "second"); hm.put("3", "third"); ct1.setProps(hm); // Используем стандартную реализацию метода clone() CloneTest ct2 = (CloneTest) ct1.clone(); // Проверяем атрибуты ct1 и ct2 на равенство System.out.println("ct1 и ct2 HashMap == test: " + (ct1.getProps() == ct2.getProps())); // Смотрим эффект от использования стандартной реализации метода clone() ct1.getProps().put("4", "fourth"); System.out.println("ct2 props:" + ct2.getProps()); ct1.setName("new"); System.out.println("ct2 name:" + ct2.getName()); } } |
В результате получается такой вывод в консоль:
1 2 |
ct1 и ct2 HashMap == test: true ct2 props:{3=third, 2=second, 1=first, 4=fourth} |
Из результатов выполнения программы видно, что стандартная реализация метода clone()
использует неполную копию и ct2 зависит от каких-либо изменений в атрибутах ct1, поэтому мы должны переопределить метод clone()
.
Важное замечание по клонированию объектов в Java
Если ваш класс содержит изменяемые объекты, то вам нужно обеспечить надлежащее выполнение метода clone()
с использованием глубокого копирования. Раскомментируйте метод clone()
и запустите программу снова.
Теперь результат будет таким:
1 2 3 |
Вызываем переопределенный метод clone() ct1 и ct2 HashMap == test: false ct2 props:{3=third, 2=second, 1=first} |
Теперь оба объекты не влияют друг на друга и клонирование работает корректно.