Метод Clone и его переопределение
Last updated: 5 мая 2025 г.Второй метод Object это метод clone
, который клонирует объект.
Происходит копирование всех полей клонируемого объекта в новый объект-клон.
Но по умолчанию методом clone в новый объект копируются только примитивные поля объекта, а ссылочные нет, поэтому clone тоже нужно переопределять.
В Java управление объектами осуществляется с помощью ссылочных переменных, и нет оператора для фактического копирования объекта, поэтому и существует clone
.
Переопределение Clone
Напрямую вызвать clone
у какого либо объекта в main нельзя, так как метод clone внутри Object объявлен protected
.
Поэтому для того чтобы вызвать clone у какого либо объекта его всегда нужно переопределять.
То есть имеется ввиду, что даже чтобы использовать стандартную реализацию clone, которая копирует только примитивные поля всё равно нужно сделать минимальное переопределение clone, как это сделано в классе SomeClass ниже.
Создадим два класса, в которых будем переопределять clone
.
Все классы, которые переопределяют clone должны реализовывать интерфейс Cloneable
. То есть видим ниже в примере программы implements Cloneable
Пример программы:
1import java.util.*;
2
3class SomeClass implements Cloneable {
4 int someVar;
5 SomeClass(int someVar){
6 this.someVar = someVar;
7 }
8
9 //неопределим clone для SomeClass
10 @Override
11 public SomeClass clone() throws CloneNotSupportedException{
12 //Слово super это супер класс то есть класс
13 // от которого наследует текущий класс
14 //Текущий класс наследует от Object.
15 //Слово super это ссылка на родительский класс Object.
16
17 //super.clone() – через супер класс клонируем
18 //текущий объект. Как уже было сказано
19 //у нового объекта copy копируются только примитивные
20 //поля объекта SomeClass. В нашем случае someVar.
21 Object obj = super.clone();
22 //Теперь новый объект clone SomeClass пока типа Object
23 //нам нужно привести его к SomeClass.
24 SomeClass someclass = (SomeClass)obj;
25 //Мы можем это сделать так как
26 //SomeClass наследует от Object.
27 //class SomeClass – extends Object;
28 //А значит имеет в своем составе
29 //все поля и методы SomeClass и в него были
30 //скопированы все НЕ ссылочные поля то есть someVar
31
32 //Ссылочных полей здесь нет
33 //поэтому такого переопределения достаточно
34
35 return someclass;//возвращаем клон
36 }
37
38 public String toString(){
39 return "SomeClass{"+ "someVar=" + someVar + ‘}’;
40 }
41}
42
43class MyClass implements Cloneable {
44 int myA;
45 SomeClass myB;
46
47 MyClass(int myA, SomeClass myB){
48 this.myA = myA;
49 this.myB = myB;
50 }
51
52 //clone должен копировать как простые
53 //так и ссылочные типы объекта
54 @Override
55 public MyClass clone() throws CloneNotSupportedException{
56 //Здесь для клонирования не ссылочных полей
57 //объекта MyClass производится те же действия
58 //что и в предыдущем классе.
59 Object obj = super.clone();
60 MyClass myclass = (MyClass)obj;
61
62 //В этом классе уже есть ссылочное поле это myB,
63 //его нужно клонировать. Для этого
64 //мы должны вызвать метод clone() из переопределения
65 //SomeClass. Он клонирует все примитивные поля
66 //из объекта myB, который является объектом
67 //SomeClass, который мы сейчас клонировали.
68 //И возвращает myclass, который является клоном.
69 myclass.myB = myB.clone();
70
71 return myclass;
72 }
73
74 public String toString(){
75 return "MyClass{" + "myA=" + myA + ", myB=" + myB + ‘}’;
76 }
77}
78
79public class CloneLesson {
80 public static void main(String[] args)
81 throws CloneNotSupportedException {
82 //Создаем объект SomeClass и объект MyClass
83 SomeClass someClass = new SomeClass(10);
84 MyClass myclass = new MyClass(10,someClass);
85 //клонируем myclass.
86 MyClass myclass1 = myclass.clone();
87
88 //Выведем на консоль поля клонируемого
89 //объекта и клона.
90 System.out.println(myclass);
91 //Как можно увидеть по результатам все поля
92 //примитивного типа и все типы ссылочные
93 //очень someClass из myclass.
94 System.out.println(myclass1);
95
96 //Теперь самое главное. Нужно точно убедиться
97 //что объекты myclass и myclass1 не ссылаются на один
98 //и тот же объект и тогда точно можно будет сказать
99 //что клонирование прошло успешно. Для этого создадим
100 //новый объект someClass и присвоим его полю myB
101 //объекта myclass1. Если клонирование прошло успешно
102 //то объект someClass никак не должен измениться
103 //в объекте myclass и убедимся что это не произошло.
104 //Если клонирование прошло успешно то объекты
105 //myclass и myclass1 будут разные, что они и отдельны.
106 someClass = new SomeClass(12);
107 myclass1.myB = someClass;
108 System.out.println(myclass);
109 System.out.println(myclass1);
110
111 //Теперь изменим ссылочное поле в myclass1
112 //и убедимся что это не изменило myclass
113 myclass1.myB.someVar = 12;
114 System.out.println(myclass);
115 System.out.println(myclass1);
116 }
117}
Вывод:

Следующие уроки
Метод Equals и его переопределение
16
мин.
Метод hashCode и его переопределение
16
мин.
Коллекции. Интерфейс List
10
мин.